func runUpdate(c *cli.Context) error { if c.IsSet("config") { setting.CustomConf = c.String("config") } setup("update.log") if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { log.GitLogger.Trace("SSH_ORIGINAL_COMMAND is empty") return nil } args := c.Args() if len(args) != 3 { log.GitLogger.Fatal(2, "Arguments received are not equal to three") } else if len(args[0]) == 0 { log.GitLogger.Fatal(2, "First argument 'refName' is empty, shouldn't use") } task := models.UpdateTask{ UUID: os.Getenv("uuid"), RefName: args[0], OldCommitID: args[1], NewCommitID: args[2], } if err := models.AddUpdateTask(&task); err != nil { log.GitLogger.Fatal(2, "AddUpdateTask: %v", err) } return nil }
// AddCommand adds a Note func AddCommand(c *cli.Context, i storage.Impl) (n storage.Note, err error) { nName, err := NoteName(c) if err != nil { return n, err } if exists := i.NoteExists(nName); exists == true { return n, fmt.Errorf("Note already exists") } n.Name = nName n.Temporary = c.Bool("t") // Only open editor if -p (read from clipboard) isnt set if c.IsSet("p") { nText, err := clipboard.ReadAll() if err != nil { return n, err } n.Text = nText } else { if err := writer.WriteNote(&n); err != nil { return n, err } } if err := i.SaveNote(&n); err != nil { return n, err } return n, nil }
func keypairsCreateCmd(c *CLI, ctx *cli.Context) { usage := func(msg string) { fmt.Printf("Usage: %s keypairs create --name=<keypair-name> <private-key-path> <certificate-path>\n", c.Name) fatal(msg) } if len(ctx.Args()) < 2 { usage("too few arguments") } if !ctx.IsSet("name") || ctx.String("name") == "" { usage("--name is required") } api := c.GetAPIClient(ctx) resourceGroup := c.GetResourceGroup(ctx) name := ctx.String("name") privateKeyPath := ctx.Args()[0] certPath := ctx.Args()[1] privateKey, err := ioutil.ReadFile(privateKeyPath) if err != nil { fatal(err.Error()) } cert, err := ioutil.ReadFile(certPath) if err != nil { fatal(err.Error()) } keypair := gondor.KeyPair{ ResourceGroup: resourceGroup.URL, Name: &name, Key: privateKey, Certificate: cert, } if err := api.KeyPairs.Create(&keypair); err != nil { fatal(err.Error()) } success("keypair created.") }
func server(c *cli.Context) { println("CIRCUIT 2015 gocircuit.org") var err error if c.Bool("docker") { cmd, err := docker.Init() if err != nil { log.Fatalf("cannot use docker: %v", err) } log.Printf("Enabling docker elements, using %s", cmd) } // parse arguments var tcpaddr = parseAddr(c) // server bind address var join n.Addr // join address of another circuit server if c.IsSet("join") { if join, err = n.ParseAddr(c.String("join")); err != nil { log.Fatalf("join address does not parse (%s)", err) } } var multicast = parseDiscover(c) // server instance working directory var varDir string if !c.IsSet("var") { varDir = path.Join(os.TempDir(), fmt.Sprintf("%s-%%W-P%04d", n.Scheme, os.Getpid())) } else { varDir = c.String("var") } // start circuit runtime addr := load(tcpaddr, varDir, readkey(c)) // tissue + locus kin, xkin, rip := tissue.NewKin() xlocus := locus.NewLocus(kin, rip) // joining switch { case join != nil: kin.ReJoin(join) case multicast != nil: log.Printf("Using UDP multicast discovery on address %s", multicast.String()) go assemble.NewAssembler(addr, multicast).AssembleServer( func(joinAddr n.Addr) { kin.ReJoin(joinAddr) }, ) default: log.Println("Singleton server.") } circuit.Listen(tissue.ServiceName, xkin) circuit.Listen(LocusName, xlocus) <-(chan int)(nil) }
func runCreateUser(c *cli.Context) error { if !c.IsSet("name") { return fmt.Errorf("Username is not specified") } else if !c.IsSet("password") { return fmt.Errorf("Password is not specified") } else if !c.IsSet("email") { return fmt.Errorf("Email is not specified") } if c.IsSet("config") { setting.CustomConf = c.String("config") } setting.NewContext() models.LoadConfigs() models.SetEngine() if err := models.CreateUser(&models.User{ Name: c.String("name"), Email: c.String("email"), Passwd: c.String("password"), IsActive: true, IsAdmin: c.Bool("admin"), }); err != nil { return fmt.Errorf("CreateUser: %v", err) } fmt.Printf("New user '%s' has been successfully created!\n", c.String("name")) return nil }
func setup(c *cli.Context) error { log.Debug("Setup") // Input validation steplibURI := c.String(CollectionKey) if steplibURI == "" { log.Fatal("No step collection specified") } copySpecJSONPath := c.String(CopySpecJSONKey) if c.IsSet(LocalCollectionKey) { log.Warn("'local' flag is deprecated") log.Warn("use 'file://' prefix in steplib path instead") fmt.Println() } if c.Bool(LocalCollectionKey) { if !strings.HasPrefix(steplibURI, "file://") { log.Warnf("Appending file path prefix (file://) to StepLib (%s)", steplibURI) steplibURI = "file://" + steplibURI log.Warnf("From now you can refer to this StepLib with URI: %s", steplibURI) log.Warnf("For example, to delete StepLib call: `stepman delete --collection %s`", steplibURI) } } // Setup if err := setupSteplib(steplibURI, false); err != nil { log.Fatalf("Setup failed, error: %s", err) } // Copy spec.json if copySpecJSONPath != "" { log.Infof("Copying spec YML to path: %s", copySpecJSONPath) route, found := stepman.ReadRoute(steplibURI) if !found { log.Fatalf("No route found for steplib (%s)", steplibURI) } sourceSpecJSONPth := stepman.GetStepSpecPath(route) if err := cmdex.CopyFile(sourceSpecJSONPth, copySpecJSONPath); err != nil { log.Fatalf("Failed to copy spec.json from (%s) to (%s), error: %s", sourceSpecJSONPth, copySpecJSONPath, err) } } return nil }
// ApplyInputSourceValue applies a BoolT value to the flagSet if required func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) { value, err := isc.BoolT(f.BoolTFlag.Name) if err != nil { return err } if !value { eachName(f.Name, func(name string) { f.set.Set(f.Name, strconv.FormatBool(value)) }) } } } return nil }
// ApplyInputSourceValue applies a int value to the flagSet if required func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) { value, err := isc.Int(f.IntFlag.Name) if err != nil { return err } if value > 0 { eachName(f.Name, func(name string) { f.set.Set(f.Name, strconv.FormatInt(int64(value), 10)) }) } } } return nil }
// ApplyInputSourceValue applies a Duration value to the flagSet if required func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) { value, err := isc.Duration(f.DurationFlag.Name) if err != nil { return err } if value > 0 { eachName(f.Name, func(name string) { f.set.Set(f.Name, value.String()) }) } } } return nil }
// ApplyInputSourceValue applies a Float64 value to the flagSet if required func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) { value, err := isc.Float64(f.Float64Flag.Name) if err != nil { return err } if value > 0 { floatStr := float64ToString(value) eachName(f.Name, func(name string) { f.set.Set(f.Name, floatStr) }) } } } return nil }
// ApplyInputSourceValue applies a generic value to the flagSet if required func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) { value, err := isc.Generic(f.GenericFlag.Name) if err != nil { return err } if value != nil { eachName(f.Name, func(name string) { f.set.Set(f.Name, value.String()) }) } } } return nil }
func runWeb(ctx *cli.Context) { if ctx.IsSet("config") { setting.CustomConf = ctx.String("config") } setting.NewContext() models.NewContext() log.Info("Peach %s", setting.AppVer) m := macaron.New() m.Use(macaron.Logger()) m.Use(macaron.Recovery()) m.Use(macaron.Statics(macaron.StaticOptions{ SkipLogging: setting.ProdMode, }, "custom/public", "public", models.HTMLRoot)) m.Use(i18n.I18n(i18n.Options{ Files: setting.Docs.Locales, DefaultLang: setting.Docs.Langs[0], })) tplDir := "templates" if setting.Page.UseCustomTpl { tplDir = "custom/templates" } m.Use(pongo2.Pongoer(pongo2.Options{ Directory: tplDir, })) m.Use(middleware.Contexter()) m.Get("/", routers.Home) m.Get("/docs", routers.Docs) m.Get("/docs/images/*", routers.DocsStatic) m.Get("/docs/*", routers.Protect, routers.Docs) m.Post("/hook", routers.Hook) m.Get("/search", routers.Search) m.Get("/*", routers.Pages) m.NotFound(routers.NotFound) listenAddr := fmt.Sprintf("0.0.0.0:%d", setting.HTTPPort) log.Info("%s Listen on %s", setting.Site.Name, listenAddr) log.Fatal("Fail to start Peach: %v", http.ListenAndServe(listenAddr, m)) }
// ApplyInputSourceValue applies a IntSlice value if required func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) { value, err := isc.IntSlice(f.IntSliceFlag.Name) if err != nil { return err } if value != nil { var sliceValue cli.IntSlice = value eachName(f.Name, func(name string) { underlyingFlag := f.set.Lookup(f.Name) if underlyingFlag != nil { underlyingFlag.Value = &sliceValue } }) } } } return nil }
func setup(c *cli.Context) error { PrintBitriseHeaderASCIIArt(c.App.Version) if c.IsSet(MinimalModeKey) { log.Warn("'minimal' flag is deprecated") log.Warn("currently setup without any flag does the same as minimal setup in previous versions") log.Warn("use 'full' flag to achive the full setup process (which includes the 'brew doctor' call)") fmt.Println() } if err := bitrise.RunSetup(c.App.Version, c.Bool(FullModeKey)); err != nil { log.Fatalf("Setup failed, error: %s", err) } log.Infoln("To start using bitrise:") log.Infoln("* cd into your project's directory (if you're not there already)") log.Infoln("* call: bitrise init") log.Infoln("* follow the guide") fmt.Println() log.Infoln("That's all :)") return nil }
func parseSQLFromArgs(ctx *cli.Context) *sqlcommand.SQLCommand { var sqlText string if !ctx.IsSet("sql") { //Trying from stdin fi, err := os.Stdin.Stat() if err != nil { panic(err) } if fi.Mode()&os.ModeNamedPipe == 0 { return nil } bio := bufio.NewReader(os.Stdin) sqlText, err = bio.ReadString(0) if err != nil && err != io.EOF { panic(err) } } else { sqlText = ctx.String("sql") } //Prepare parameters colParams, e := parameters.GetInstance().All() if e != nil { panic(e) } params := colParams.Get() paramsArgs := ctx.StringSlice("param") for i := 0; i < len(paramsArgs); i++ { newparam, e := paramsreplace.Replace(paramsArgs[i], params) if e != nil { logger.Error.Println(e) } else { paramsArgs[i] = newparam } } return sqlcommand.New(sqlText, paramsArgs) }
func parseOthersFlagsForRunContext(ctx *cli.Context, ctxRun *action.Context) error { if ctx.IsSet("format") { format := ctx.String("format") subformat := "" //TODO: refactor it! if strings.Contains(format, "raw:") { subformat = format[len("raw:"):] format = "raw" } if strings.Contains(format, "table:") { subformat = format[len("table:"):] format = "table" } if strings.Contains(format, "json:") { subformat = format[len("json:"):] format = "json" } if strings.Contains(format, "xml:") { subformat = format[len("xml:"):] format = "xml" } switch format { case "table", "raw", "json", "xml": ctxRun.Set("format", format) ctxRun.Set("subformat", subformat) break default: return fmt.Errorf("Unknown format:%s", format) } } else { ctxRun.Set("format", "raw") } if ctx.IsSet("timeout") { ctxRun.Set("timeout", ctx.Int("timeout")) } if ctx.IsSet("commit") { ctxRun.Set("commit", ctx.Bool("commit")) } return nil }
// run is the main run target. func run(c *cli.Context) error { obj := &Main{} obj.Program = c.App.Name obj.Version = c.App.Version if h := c.String("hostname"); c.IsSet("hostname") && h != "" { obj.Hostname = &h } if s := c.String("prefix"); c.IsSet("prefix") && s != "" { obj.Prefix = &s } obj.TmpPrefix = c.Bool("tmp-prefix") obj.AllowTmpPrefix = c.Bool("allow-tmp-prefix") if _ = c.String("code"); c.IsSet("code") { if obj.GAPI != nil { return fmt.Errorf("Can't combine code GAPI with existing GAPI.") } // TODO: implement DSL GAPI //obj.GAPI = &dsl.GAPI{ // Code: &s, //} return fmt.Errorf("The Code GAPI is not implemented yet!") // TODO: DSL } if y := c.String("yaml"); c.IsSet("yaml") { if obj.GAPI != nil { return fmt.Errorf("Can't combine YAML GAPI with existing GAPI.") } obj.GAPI = &yamlgraph.GAPI{ File: &y, } } if p := c.String("puppet"); c.IsSet("puppet") { if obj.GAPI != nil { return fmt.Errorf("Can't combine puppet GAPI with existing GAPI.") } obj.GAPI = &puppet.GAPI{ PuppetParam: &p, PuppetConf: c.String("puppet-conf"), } } obj.Remotes = c.StringSlice("remote") // FIXME: GAPI-ify somehow? obj.NoWatch = c.Bool("no-watch") obj.Noop = c.Bool("noop") obj.Graphviz = c.String("graphviz") obj.GraphvizFilter = c.String("graphviz-filter") obj.ConvergedTimeout = c.Int("converged-timeout") obj.MaxRuntime = uint(c.Int("max-runtime")) obj.Seeds = c.StringSlice("seeds") obj.ClientURLs = c.StringSlice("client-urls") obj.ServerURLs = c.StringSlice("server-urls") obj.IdealClusterSize = c.Int("ideal-cluster-size") obj.NoServer = c.Bool("no-server") obj.CConns = uint16(c.Int("cconns")) obj.AllowInteractive = c.Bool("allow-interactive") obj.SSHPrivIDRsa = c.String("ssh-priv-id-rsa") obj.NoCaching = c.Bool("no-caching") obj.Depth = uint16(c.Int("depth")) if err := obj.Init(); err != nil { return err } // install the exit signal handler exit := make(chan struct{}) defer close(exit) go func() { signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) // catch ^C //signal.Notify(signals, os.Kill) // catch signals signal.Notify(signals, syscall.SIGTERM) select { case sig := <-signals: // any signal will do if sig == os.Interrupt { log.Println("Interrupted by ^C") obj.Exit(nil) return } log.Println("Interrupted by signal") obj.Exit(fmt.Errorf("Killed by %v", sig)) return case <-exit: return } }() if err := obj.Run(); err != nil { return err //return cli.NewExitError(err.Error(), 1) // TODO: ? //return cli.NewExitError("", 1) // TODO: ? } return nil }
// run is the main run target. func run(c *cli.Context) error { var start = time.Now().UnixNano() log.Printf("This is: %v, version: %v", program, version) log.Printf("Main: Start: %v", start) hostname, _ := os.Hostname() // allow passing in the hostname, instead of using --hostname if c.IsSet("file") { if config := gconfig.ParseConfigFromFile(c.String("file")); config != nil { if h := config.Hostname; h != "" { hostname = h } } } if c.IsSet("hostname") { // override by cli if h := c.String("hostname"); h != "" { hostname = h } } noop := c.Bool("noop") seeds, err := etcdtypes.NewURLs( util.FlattenListWithSplit(c.StringSlice("seeds"), []string{",", ";", " "}), ) if err != nil && len(c.StringSlice("seeds")) > 0 { log.Printf("Main: Error: seeds didn't parse correctly!") return cli.NewExitError("", 1) } clientURLs, err := etcdtypes.NewURLs( util.FlattenListWithSplit(c.StringSlice("client-urls"), []string{",", ";", " "}), ) if err != nil && len(c.StringSlice("client-urls")) > 0 { log.Printf("Main: Error: clientURLs didn't parse correctly!") return cli.NewExitError("", 1) } serverURLs, err := etcdtypes.NewURLs( util.FlattenListWithSplit(c.StringSlice("server-urls"), []string{",", ";", " "}), ) if err != nil && len(c.StringSlice("server-urls")) > 0 { log.Printf("Main: Error: serverURLs didn't parse correctly!") return cli.NewExitError("", 1) } idealClusterSize := uint16(c.Int("ideal-cluster-size")) if idealClusterSize < 1 { log.Printf("Main: Error: idealClusterSize should be at least one!") return cli.NewExitError("", 1) } if c.IsSet("file") && c.IsSet("puppet") { log.Println("Main: Error: the --file and --puppet parameters cannot be used together!") return cli.NewExitError("", 1) } if c.Bool("no-server") && len(c.StringSlice("remote")) > 0 { // TODO: in this case, we won't be able to tunnel stuff back to // here, so if we're okay with every remote graph running in an // isolated mode, then this is okay. Improve on this if there's // someone who really wants to be able to do this. log.Println("Main: Error: the --no-server and --remote parameters cannot be used together!") return cli.NewExitError("", 1) } cConns := uint16(c.Int("cconns")) if cConns < 0 { log.Printf("Main: Error: --cconns should be at least zero!") return cli.NewExitError("", 1) } if c.IsSet("converged-timeout") && cConns > 0 && len(c.StringSlice("remote")) > c.Int("cconns") { log.Printf("Main: Error: combining --converged-timeout with more remotes than available connections will never converge!") return cli.NewExitError("", 1) } depth := uint16(c.Int("depth")) if depth < 0 { // user should not be using this argument manually log.Printf("Main: Error: negative values for --depth are not permitted!") return cli.NewExitError("", 1) } if c.IsSet("prefix") && c.Bool("tmp-prefix") { log.Println("Main: Error: combining --prefix and the request for a tmp prefix is illogical!") return cli.NewExitError("", 1) } if s := c.String("prefix"); c.IsSet("prefix") && s != "" { prefix = s } // make sure the working directory prefix exists if c.Bool("tmp-prefix") || os.MkdirAll(prefix, 0770) != nil { if c.Bool("tmp-prefix") || c.Bool("allow-tmp-prefix") { if prefix, err = ioutil.TempDir("", program+"-"); err != nil { log.Printf("Main: Error: Can't create temporary prefix!") return cli.NewExitError("", 1) } log.Println("Main: Warning: Working prefix directory is temporary!") } else { log.Printf("Main: Error: Can't create prefix!") return cli.NewExitError("", 1) } } log.Printf("Main: Working prefix is: %s", prefix) var wg sync.WaitGroup exit := make(chan bool) // exit signal var G, fullGraph *pgraph.Graph // exit after `max-runtime` seconds for no reason at all... if i := c.Int("max-runtime"); i > 0 { go func() { time.Sleep(time.Duration(i) * time.Second) exit <- true }() } // setup converger converger := converger.NewConverger( c.Int("converged-timeout"), nil, // stateFn gets added in by EmbdEtcd ) go converger.Loop(true) // main loop for converger, true to start paused // embedded etcd if len(seeds) == 0 { log.Printf("Main: Seeds: No seeds specified!") } else { log.Printf("Main: Seeds(%v): %v", len(seeds), seeds) } EmbdEtcd := etcd.NewEmbdEtcd( hostname, seeds, clientURLs, serverURLs, c.Bool("no-server"), idealClusterSize, prefix, converger, ) if EmbdEtcd == nil { // TODO: verify EmbdEtcd is not nil below... log.Printf("Main: Etcd: Creation failed!") exit <- true } else if err := EmbdEtcd.Startup(); err != nil { // startup (returns when etcd main loop is running) log.Printf("Main: Etcd: Startup failed: %v", err) exit <- true } convergerStateFn := func(b bool) error { // exit if we are using the converged-timeout and we are the // root node. otherwise, if we are a child node in a remote // execution hierarchy, we should only notify our converged // state and wait for the parent to trigger the exit. if depth == 0 && c.Int("converged-timeout") >= 0 { if b { log.Printf("Converged for %d seconds, exiting!", c.Int("converged-timeout")) exit <- true // trigger an exit! } return nil } // send our individual state into etcd for others to see return etcd.EtcdSetHostnameConverged(EmbdEtcd, hostname, b) // TODO: what should happen on error? } if EmbdEtcd != nil { converger.SetStateFn(convergerStateFn) } exitchan := make(chan struct{}) // exit on close go func() { startchan := make(chan struct{}) // start signal go func() { startchan <- struct{}{} }() file := c.String("file") var configchan chan bool var puppetchan <-chan time.Time if !c.Bool("no-watch") && c.IsSet("file") { configchan = ConfigWatch(file) } else if c.IsSet("puppet") { interval := puppet.PuppetInterval(c.String("puppet-conf")) puppetchan = time.Tick(time.Duration(interval) * time.Second) } log.Println("Etcd: Starting...") etcdchan := etcd.EtcdWatch(EmbdEtcd) first := true // first loop or not for { log.Println("Main: Waiting...") select { case <-startchan: // kick the loop once at start // pass case b := <-etcdchan: if !b { // ignore the message continue } // everything else passes through to cause a compile! case <-puppetchan: // nothing, just go on case msg := <-configchan: if c.Bool("no-watch") || !msg { continue // not ready to read config } // XXX: case compile_event: ... // ... case <-exitchan: return } var config *gconfig.GraphConfig if c.IsSet("file") { config = gconfig.ParseConfigFromFile(file) } else if c.IsSet("puppet") { config = puppet.ParseConfigFromPuppet(c.String("puppet"), c.String("puppet-conf")) } if config == nil { log.Printf("Config: Parse failure") continue } if config.Hostname != "" && config.Hostname != hostname { log.Printf("Config: Hostname changed, ignoring config!") continue } config.Hostname = hostname // set it in case it was "" // run graph vertex LOCK... if !first { // TODO: we can flatten this check out I think converger.Pause() // FIXME: add sync wait? G.Pause() // sync } // build graph from yaml file on events (eg: from etcd) // we need the vertices to be paused to work on them if newFullgraph, err := config.NewGraphFromConfig(fullGraph, EmbdEtcd, noop); err == nil { // keep references to all original elements fullGraph = newFullgraph } else { log.Printf("Config: Error making new graph from config: %v", err) // unpause! if !first { G.Start(&wg, first) // sync converger.Start() // after G.Start() } continue } G = fullGraph.Copy() // copy to active graph // XXX: do etcd transaction out here... G.AutoEdges() // add autoedges; modifies the graph G.AutoGroup() // run autogroup; modifies the graph // TODO: do we want to do a transitive reduction? log.Printf("Graph: %v", G) // show graph err := G.ExecGraphviz(c.String("graphviz-filter"), c.String("graphviz")) if err != nil { log.Printf("Graphviz: %v", err) } else { log.Printf("Graphviz: Successfully generated graph!") } G.AssociateData(converger) // G.Start(...) needs to be synchronous or wait, // because if half of the nodes are started and // some are not ready yet and the EtcdWatch // loops, we'll cause G.Pause(...) before we // even got going, thus causing nil pointer errors G.Start(&wg, first) // sync converger.Start() // after G.Start() first = false } }() configWatcher := NewConfigWatcher() events := configWatcher.Events() if !c.Bool("no-watch") { configWatcher.Add(c.StringSlice("remote")...) // add all the files... } else { events = nil // signal that no-watch is true } // initialize the add watcher, which calls the f callback on map changes convergerCb := func(f func(map[string]bool) error) (func(), error) { return etcd.EtcdAddHostnameConvergedWatcher(EmbdEtcd, f) } // build remotes struct for remote ssh remotes := remote.NewRemotes( EmbdEtcd.LocalhostClientURLs().StringSlice(), []string{etcd.DefaultClientURL}, noop, c.StringSlice("remote"), // list of files events, // watch for file changes cConns, c.Bool("allow-interactive"), c.String("ssh-priv-id-rsa"), !c.Bool("no-caching"), depth, prefix, converger, convergerCb, program, ) // TODO: is there any benefit to running the remotes above in the loop? // wait for etcd to be running before we remote in, which we do above! go remotes.Run() if !c.IsSet("file") && !c.IsSet("puppet") { converger.Start() // better start this for empty graphs } log.Println("Main: Running...") waitForSignal(exit) // pass in exit channel to watch log.Println("Destroy...") configWatcher.Close() // stop sending file changes to remotes remotes.Exit() // tell all the remote connections to shutdown; waits! G.Exit() // tell all the children to exit // tell inner main loop to exit close(exitchan) // cleanup etcd main loop last so it can process everything first if err := EmbdEtcd.Destroy(); err != nil { // shutdown and cleanup etcd log.Printf("Etcd exited poorly with: %v", err) } if global.DEBUG { log.Printf("Graph: %v", G) } wg.Wait() // wait for primary go routines to exit // TODO: wait for each vertex to exit... log.Println("Goodbye!") return nil }
func (c *Config) commonSparse(context *cli.Context) *Config { s := *c if s.XMPPServer == DefaultConfig.XMPPServer { s.XMPPServer = "" } if !context.IsSet("xmpp-port") && s.XMPPPort == DefaultConfig.XMPPPort { s.XMPPPort = 0 } if !context.IsSet("xmpp-ping-timeout") && s.XMPPPingTimeout == DefaultConfig.XMPPPingTimeout { s.XMPPPingTimeout = "" } if !context.IsSet("xmpp-ping-interval") && s.XMPPPingInterval == DefaultConfig.XMPPPingInterval { s.XMPPPingInterval = "" } if s.GCPBaseURL == DefaultConfig.GCPBaseURL { s.GCPBaseURL = "" } if s.GCPOAuthClientID == DefaultConfig.GCPOAuthClientID { s.GCPOAuthClientID = "" } if s.GCPOAuthClientSecret == DefaultConfig.GCPOAuthClientSecret { s.GCPOAuthClientSecret = "" } if s.GCPOAuthAuthURL == DefaultConfig.GCPOAuthAuthURL { s.GCPOAuthAuthURL = "" } if s.GCPOAuthTokenURL == DefaultConfig.GCPOAuthTokenURL { s.GCPOAuthTokenURL = "" } if !context.IsSet("gcp-max-concurrent-downloads") && s.GCPMaxConcurrentDownloads == DefaultConfig.GCPMaxConcurrentDownloads { s.GCPMaxConcurrentDownloads = 0 } if !context.IsSet("native-job-queue-size") && s.NativeJobQueueSize == DefaultConfig.NativeJobQueueSize { s.NativeJobQueueSize = 0 } if !context.IsSet("native-printer-poll-interval") && s.NativePrinterPollInterval == DefaultConfig.NativePrinterPollInterval { s.NativePrinterPollInterval = "" } if !context.IsSet("cups-job-full-username") && reflect.DeepEqual(s.CUPSJobFullUsername, DefaultConfig.CUPSJobFullUsername) { s.CUPSJobFullUsername = nil } if !context.IsSet("prefix-job-id-to-job-title") && reflect.DeepEqual(s.PrefixJobIDToJobTitle, DefaultConfig.PrefixJobIDToJobTitle) { s.PrefixJobIDToJobTitle = nil } if !context.IsSet("display-name-prefix") && s.DisplayNamePrefix == DefaultConfig.DisplayNamePrefix { s.DisplayNamePrefix = "" } if !context.IsSet("local-port-low") && s.LocalPortLow == DefaultConfig.LocalPortLow { s.LocalPortLow = 0 } if !context.IsSet("local-port-high") && s.LocalPortHigh == DefaultConfig.LocalPortHigh { s.LocalPortHigh = 0 } return &s }
// // handleCommand is a generic wrapper for handling commands, or more precisely their errors // func handleCommand(cx *cli.Context, options []string, cmd *cliCommand, method func(*formatter, *cli.Context, *cliCommand) error) error { // step: handle any panics in the command defer func() { if r := recover(); r != nil { fmt.Fprintf(os.Stderr, "[error] internal error occurred, message: %s", r) os.Exit(1) } }() // step: check the required options were specified for _, k := range options { items := strings.Split(k, ":") if len(items) != 3 { panic("invalid required option definition, SCOPE:NAME:TYPE") } name := items[1] // // @Fix the cli lib IsSet does not check if the option was set by a environment variable, the // issue https://github.com/urfave/cli/issues/294 highlights problem. As a consequence, we can't determine // if the variable is actually set. The hack below attempts to remedy it. // var invalid bool switch scope := items[0]; scope { case "g": switch t := items[2]; t { case "s": invalid = !cx.GlobalIsSet(name) && cx.String(name) == "" case "a": invalid = !cx.GlobalIsSet(name) && len(cx.GlobalStringSlice(name)) == 0 } if invalid { printError("the global option: '%s' is required", name) } default: switch t := items[2]; t { case "s": invalid = !cx.IsSet(name) && cx.String(name) == "" case "a": invalid = !cx.IsSet(name) && len(cx.StringSlice(name)) == 0 } if invalid { printError("the command option: '%s' is required", name) } } } // step: create a cli output writer, err := newFormatter(cx.GlobalString("format"), os.Stdout) if err != nil { printError("error: %s", err) } // step: call the command and handle any errors if err := method(writer, cx, cmd); err != nil { printError("operation failed, error: %s", err) } return nil }
func runWeb(ctx *cli.Context) error { if ctx.IsSet("config") { setting.CustomConf = ctx.String("config") } routers.GlobalInit() checkVersion() m := newMacaron() reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true}) ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView}) ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true}) reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) bindIgnErr := binding.BindIgnErr // FIXME: not all routes need go through same middlewares. // Especially some AJAX requests, we can reduce middleware number to improve performance. // Routers. m.Get("/", ignSignIn, routers.Home) m.Group("/explore", func() { m.Get("", func(ctx *context.Context) { ctx.Redirect(setting.AppSubUrl + "/explore/repos") }) m.Get("/repos", routers.ExploreRepos) m.Get("/users", routers.ExploreUsers) m.Get("/organizations", routers.ExploreOrganizations) }, ignSignIn) m.Combo("/install", routers.InstallInit).Get(routers.Install). Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost) m.Get("/^:type(issues|pulls)$", reqSignIn, user.Issues) // ***** START: User ***** m.Group("/user", func() { m.Get("/login", user.SignIn) m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost) m.Get("/sign_up", user.SignUp) m.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost) m.Get("/reset_password", user.ResetPasswd) m.Post("/reset_password", user.ResetPasswdPost) }, reqSignOut) m.Group("/user/settings", func() { m.Get("", user.Settings) m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost) m.Combo("/avatar").Get(user.SettingsAvatar). Post(binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost) m.Post("/avatar/delete", user.SettingsDeleteAvatar) m.Combo("/email").Get(user.SettingsEmails). Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost) m.Post("/email/delete", user.DeleteEmail) m.Get("/password", user.SettingsPassword) m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost) m.Combo("/ssh").Get(user.SettingsSSHKeys). Post(bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost) m.Post("/ssh/delete", user.DeleteSSHKey) m.Combo("/applications").Get(user.SettingsApplications). Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost) m.Post("/applications/delete", user.SettingsDeleteApplication) m.Route("/delete", "GET,POST", user.SettingsDelete) }, reqSignIn, func(ctx *context.Context) { ctx.Data["PageIsUserSettings"] = true }) m.Group("/user", func() { // r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) m.Any("/activate", user.Activate) m.Any("/activate_email", user.ActivateEmail) m.Get("/email2user", user.Email2User) m.Get("/forget_password", user.ForgotPasswd) m.Post("/forget_password", user.ForgotPasswdPost) m.Get("/logout", user.SignOut) }) // ***** END: User ***** adminReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true}) // ***** START: Admin ***** m.Group("/admin", func() { m.Get("", adminReq, admin.Dashboard) m.Get("/config", admin.Config) m.Post("/config/test_mail", admin.SendTestMail) m.Get("/monitor", admin.Monitor) m.Group("/users", func() { m.Get("", admin.Users) m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(auth.AdminCrateUserForm{}), admin.NewUserPost) m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) m.Post("/:userid/delete", admin.DeleteUser) }) m.Group("/orgs", func() { m.Get("", admin.Organizations) }) m.Group("/repos", func() { m.Get("", admin.Repos) m.Post("/delete", admin.DeleteRepo) }) m.Group("/auths", func() { m.Get("", admin.Authentications) m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost) m.Combo("/:authid").Get(admin.EditAuthSource). Post(bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) m.Post("/:authid/delete", admin.DeleteAuthSource) }) m.Group("/notices", func() { m.Get("", admin.Notices) m.Post("/delete", admin.DeleteNotices) m.Get("/empty", admin.EmptyNotices) }) }, adminReq) // ***** END: Admin ***** m.Group("", func() { m.Group("/:username", func() { m.Get("", user.Profile) m.Get("/followers", user.Followers) m.Get("/following", user.Following) m.Get("/stars", user.Stars) }) m.Get("/attachments/:uuid", func(ctx *context.Context) { attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid")) if err != nil { if models.IsErrAttachmentNotExist(err) { ctx.Error(404) } else { ctx.Handle(500, "GetAttachmentByUUID", err) } return } fr, err := os.Open(attach.LocalPath()) if err != nil { ctx.Handle(500, "Open", err) return } defer fr.Close() ctx.Header().Set("Cache-Control", "public,max-age=86400") ctx.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name)) // Fix #312. Attachments with , in their name are not handled correctly by Google Chrome. // We must put the name in " manually. if err = repo.ServeData(ctx, "\""+attach.Name+"\"", fr); err != nil { ctx.Handle(500, "ServeData", err) return } }) m.Post("/issues/attachments", repo.UploadIssueAttachment) }, ignSignIn) m.Group("/:username", func() { m.Get("/action/:action", user.Action) }, reqSignIn) if macaron.Env == macaron.DEV { m.Get("/template/*", dev.TemplatePreview) } reqRepoAdmin := context.RequireRepoAdmin() reqRepoWriter := context.RequireRepoWriter() // ***** START: Organization ***** m.Group("/org", func() { m.Get("/create", org.Create) m.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost) m.Group("/:org", func() { m.Get("/dashboard", user.Dashboard) m.Get("/^:type(issues|pulls)$", user.Issues) m.Get("/members", org.Members) m.Get("/members/action/:action", org.MembersAction) m.Get("/teams", org.Teams) }, context.OrgAssignment(true)) m.Group("/:org", func() { m.Get("/teams/:team", org.TeamMembers) m.Get("/teams/:team/repositories", org.TeamRepositories) m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction) m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction) }, context.OrgAssignment(true, false, true)) m.Group("/:org", func() { m.Get("/teams/new", org.NewTeam) m.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost) m.Get("/teams/:team/edit", org.EditTeam) m.Post("/teams/:team/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost) m.Post("/teams/:team/delete", org.DeleteTeam) m.Group("/settings", func() { m.Combo("").Get(org.Settings). Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost) m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), org.SettingsAvatar) m.Post("/avatar/delete", org.SettingsDeleteAvatar) m.Group("/hooks", func() { m.Get("", org.Webhooks) m.Post("/delete", org.DeleteWebhook) m.Get("/:type/new", repo.WebhooksNew) m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Get("/:id", repo.WebHooksEdit) m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) }) m.Route("/delete", "GET,POST", org.SettingsDelete) }) m.Route("/invitations/new", "GET,POST", org.Invitation) }, context.OrgAssignment(true, true)) }, reqSignIn) // ***** END: Organization ***** // ***** START: Repository ***** m.Group("/repo", func() { m.Get("/create", repo.Create) m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost) m.Get("/migrate", repo.Migrate) m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost) m.Combo("/fork/:repoid").Get(repo.Fork). Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) }, reqSignIn) m.Group("/:username/:reponame", func() { m.Group("/settings", func() { m.Combo("").Get(repo.Settings). Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost) m.Group("/collaboration", func() { m.Combo("").Get(repo.Collaboration).Post(repo.CollaborationPost) m.Post("/access_mode", repo.ChangeCollaborationAccessMode) m.Post("/delete", repo.DeleteCollaboration) }) m.Group("/hooks", func() { m.Get("", repo.Webhooks) m.Post("/delete", repo.DeleteWebhook) m.Get("/:type/new", repo.WebhooksNew) m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) m.Get("/:id", repo.WebHooksEdit) m.Post("/:id/test", repo.TestWebhook) m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Group("/git", func() { m.Get("", repo.GitHooks) m.Combo("/:name").Get(repo.GitHooksEdit). Post(repo.GitHooksEditPost) }, context.GitHookService()) }) m.Group("/keys", func() { m.Combo("").Get(repo.DeployKeys). Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.DeployKeysPost) m.Post("/delete", repo.DeleteDeployKey) }) }, func(ctx *context.Context) { ctx.Data["PageIsSettings"] = true }) }, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef()) m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action) m.Group("/:username/:reponame", func() { // FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest. // So they can apply their own enable/disable logic on routers. m.Group("/issues", func() { m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue). Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost) m.Group("/:index", func() { m.Post("/label", repo.UpdateIssueLabel) m.Post("/milestone", repo.UpdateIssueMilestone) m.Post("/assignee", repo.UpdateIssueAssignee) }, reqRepoWriter) m.Group("/:index", func() { m.Post("/title", repo.UpdateIssueTitle) m.Post("/content", repo.UpdateIssueContent) m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment) }) }) m.Group("/comments/:id", func() { m.Post("", repo.UpdateCommentContent) m.Post("/delete", repo.DeleteComment) }) m.Group("/labels", func() { m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel) m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel) m.Post("/delete", repo.DeleteLabel) m.Post("/initialize", bindIgnErr(auth.InitializeLabelsForm{}), repo.InitializeLabels) }, reqRepoWriter, context.RepoRef()) m.Group("/milestones", func() { m.Combo("/new").Get(repo.NewMilestone). Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost) m.Get("/:id/edit", repo.EditMilestone) m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost) m.Get("/:id/:action", repo.ChangeMilestonStatus) m.Post("/delete", repo.DeleteMilestone) }, reqRepoWriter, context.RepoRef()) m.Group("/releases", func() { m.Get("/new", repo.NewRelease) m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost) m.Post("/delete", repo.DeleteRelease) }, reqRepoWriter, context.RepoRef()) m.Group("/releases", func() { m.Get("/edit/*", repo.EditRelease) m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) }, reqRepoWriter, func(ctx *context.Context) { var err error ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) if err != nil { ctx.Handle(500, "GetBranchCommit", err) return } ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount() if err != nil { ctx.Handle(500, "CommitsCount", err) return } ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount }) m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest). Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost) m.Group("", func() { m.Combo("/_edit/*").Get(repo.EditFile). Post(bindIgnErr(auth.EditRepoFileForm{}), repo.EditFilePost) m.Combo("/_new/*").Get(repo.NewFile). Post(bindIgnErr(auth.EditRepoFileForm{}), repo.NewFilePost) m.Post("/_preview/*", bindIgnErr(auth.EditPreviewDiffForm{}), repo.DiffPreviewPost) m.Combo("/_delete/*").Get(repo.DeleteFile). Post(bindIgnErr(auth.DeleteRepoFileForm{}), repo.DeleteFilePost) m.Group("", func() { m.Combo("/_upload/*").Get(repo.UploadFile). Post(bindIgnErr(auth.UploadRepoFileForm{}), repo.UploadFilePost) m.Post("/upload-file", repo.UploadFileToServer) m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer) }, func(ctx *context.Context) { if !setting.Repository.Upload.Enabled { ctx.Handle(404, "", nil) return } }) }, reqRepoWriter, context.RepoRef(), func(ctx *context.Context) { if !ctx.Repo.Repository.CanEnableEditor() || ctx.Repo.IsViewCommit { ctx.Handle(404, "", nil) return } }) }, reqSignIn, context.RepoAssignment(), repo.MustBeNotBare) m.Group("/:username/:reponame", func() { m.Group("", func() { m.Get("/releases", repo.Releases) m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues) m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue) m.Get("/labels/", repo.RetrieveLabels, repo.Labels) m.Get("/milestones", repo.Milestones) }, context.RepoRef()) // m.Get("/branches", repo.Branches) m.Group("/wiki", func() { m.Get("/?:page", repo.Wiki) m.Get("/_pages", repo.WikiPages) m.Group("", func() { m.Combo("/_new").Get(repo.NewWiki). Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost) m.Combo("/:page/_edit").Get(repo.EditWiki). Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost) m.Post("/:page/delete", repo.DeleteWikiPagePost) }, reqSignIn, reqRepoWriter) }, repo.MustEnableWiki, context.RepoRef()) m.Get("/archive/*", repo.Download) m.Group("/pulls/:index", func() { m.Get("/commits", context.RepoRef(), repo.ViewPullCommits) m.Get("/files", context.RepoRef(), repo.ViewPullFiles) m.Post("/merge", reqRepoWriter, repo.MergePullRequest) }, repo.MustAllowPulls) m.Group("", func() { m.Get("/src/*", repo.Home) m.Get("/raw/*", repo.SingleDownload) m.Get("/commits/*", repo.RefCommits) m.Get("/commit/:sha([a-z0-9]{7,40})$", repo.Diff) m.Get("/forks", repo.Forks) }, context.RepoRef()) m.Get("/commit/:sha([a-z0-9]{7,40})\\.:ext(patch|diff)", repo.RawDiff) m.Get("/compare/:before([a-z0-9]{7,40})\\.\\.\\.:after([a-z0-9]{7,40})", repo.CompareDiff) }, ignSignIn, context.RepoAssignment(), repo.MustBeNotBare) m.Group("/:username/:reponame", func() { m.Get("/stars", repo.Stars) m.Get("/watchers", repo.Watchers) }, ignSignIn, context.RepoAssignment(), context.RepoRef()) m.Group("/:username", func() { m.Group("/:reponame", func() { m.Get("", repo.Home) m.Get("\\.git$", repo.Home) }, ignSignIn, context.RepoAssignment(true), context.RepoRef()) m.Group("/:reponame", func() { m.Any("/*", ignSignInAndCsrf, repo.HTTP) m.Head("/tasks/trigger", repo.TriggerTask) }) }) // ***** END: Repository ***** m.Group("/api", func() { apiv1.RegisterRoutes(m) }, ignSignIn) // robots.txt m.Get("/robots.txt", func(ctx *context.Context) { if setting.HasRobotsTxt { ctx.ServeFileContent(path.Join(setting.CustomPath, "robots.txt")) } else { ctx.Error(404) } }) // Not found handler. m.NotFound(routers.NotFound) // Flag for port number in case first time run conflict. if ctx.IsSet("port") { setting.AppUrl = strings.Replace(setting.AppUrl, setting.HTTPPort, ctx.String("port"), 1) setting.HTTPPort = ctx.String("port") } var listenAddr string if setting.Protocol == setting.UNIX_SOCKET { listenAddr = fmt.Sprintf("%s", setting.HTTPAddr) } else { listenAddr = fmt.Sprintf("%s:%s", setting.HTTPAddr, setting.HTTPPort) } log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl) var err error switch setting.Protocol { case setting.HTTP: err = http.ListenAndServe(listenAddr, m) case setting.HTTPS: server := &http.Server{Addr: listenAddr, TLSConfig: &tls.Config{MinVersion: tls.VersionTLS10}, Handler: m} err = server.ListenAndServeTLS(setting.CertFile, setting.KeyFile) case setting.FCGI: err = fcgi.Serve(nil, m) case setting.UNIX_SOCKET: os.Remove(listenAddr) var listener *net.UnixListener listener, err = net.ListenUnix("unix", &net.UnixAddr{listenAddr, "unix"}) if err != nil { break // Handle error after switch } // FIXME: add proper implementation of signal capture on all protocols // execute this on SIGTERM or SIGINT: listener.Close() if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil { log.Fatal(4, "Failed to set permission of unix socket: %v", err) } err = http.Serve(listener, m) default: log.Fatal(4, "Invalid protocol: %s", setting.Protocol) } if err != nil { log.Fatal(4, "Fail to start server: %v", err) } return nil }
func initConfigFile(context *cli.Context) { var localEnable bool if runtime.GOOS == "windows" { // Remove this if block when Privet support is added to Windows. localEnable = false } else if context.IsSet("local-printing-enable") { localEnable = context.Bool("local-printing-enable") } else { fmt.Println("\"Local printing\" means that clients print directly to the connector via") fmt.Println("local subnet, and that an Internet connection is neither necessary nor used.") localEnable = scanYesOrNo("Enable local printing?") } var cloudEnable bool if runtime.GOOS == "windows" { // Remove this if block when Privet support is added to Windows. cloudEnable = true } else if context.IsSet("cloud-printing-enable") { cloudEnable = context.Bool("cloud-printing-enable") } else { fmt.Println("\"Cloud printing\" means that clients can print from anywhere on the Internet,") fmt.Println("and that printers must be explicitly shared with users.") cloudEnable = scanYesOrNo("Enable cloud printing?") } if !localEnable && !cloudEnable { log.Fatalln("Try again. Either local or cloud (or both) must be enabled for the connector to do something.") } var config *lib.Config var xmppJID, robotRefreshToken, userRefreshToken, shareScope, proxyName string if cloudEnable { if context.IsSet("share-scope") { shareScope = context.String("share-scope") } else if scanYesOrNo("Retain the user OAuth token to enable automatic sharing?") { shareScope = scanNonEmptyString("User or group email address to share with:") } if context.IsSet("proxy-name") { proxyName = context.String("proxy-name") } else { proxyName = scanNonEmptyString("Proxy name for this connector:") } var userClient *http.Client if context.IsSet("gcp-user-refresh-token") { userClient = getUserClientFromToken(context) if shareScope != "" { userRefreshToken = context.String("gcp-user-refresh-token") } } else { var urt string userClient, urt = getUserClientFromUser(context) if shareScope != "" { userRefreshToken = urt } } xmppJID, robotRefreshToken = createRobotAccount(context, userClient) fmt.Println("Acquired OAuth credentials for robot account") fmt.Println("") config = createCloudConfig(context, xmppJID, robotRefreshToken, userRefreshToken, shareScope, proxyName, localEnable) } else { config = createLocalConfig(context) } configFilename := writeConfigFile(context, config) fmt.Printf("The config file %s is ready to rock.\n", configFilename) if cloudEnable { fmt.Println("Keep it somewhere safe, as it contains an OAuth refresh token.") } socketDirectory := filepath.Dir(context.String("monitor-socket-filename")) if _, err := os.Stat(socketDirectory); os.IsNotExist(err) { fmt.Println("") fmt.Printf("When the connector runs, be sure the socket directory %s exists.\n", socketDirectory) } }
func runDump(ctx *cli.Context) error { if ctx.IsSet("config") { setting.CustomConf = ctx.String("config") } setting.NewContext() models.LoadConfigs() models.SetEngine() tmpDir := ctx.String("tempdir") if _, err := os.Stat(tmpDir); os.IsNotExist(err) { log.Fatalf("Path does not exist: %s", tmpDir) } TmpWorkDir, err := ioutil.TempDir(tmpDir, "gogs-dump-") if err != nil { log.Fatalf("Fail to create tmp work directory: %v", err) } log.Printf("Creating tmp work dir: %s", TmpWorkDir) reposDump := path.Join(TmpWorkDir, "gogs-repo.zip") dbDump := path.Join(TmpWorkDir, "gogs-db.sql") log.Printf("Dumping local repositories...%s", setting.RepoRootPath) zip.Verbose = ctx.Bool("verbose") if err := zip.PackTo(setting.RepoRootPath, reposDump, true); err != nil { log.Fatalf("Fail to dump local repositories: %v", err) } log.Printf("Dumping database...") if err := models.DumpDatabase(dbDump); err != nil { log.Fatalf("Fail to dump database: %v", err) } fileName := fmt.Sprintf("gogs-dump-%d.zip", time.Now().Unix()) log.Printf("Packing dump files...") z, err := zip.Create(fileName) if err != nil { os.Remove(fileName) log.Fatalf("Fail to create %s: %v", fileName, err) } if err := z.AddFile("gogs-repo.zip", reposDump); err != nil { log.Fatalf("Fail to include gogs-repo.zip: %v", err) } if err := z.AddFile("gogs-db.sql", dbDump); err != nil { log.Fatalf("Fail to include gogs-db.sql: %v", err) } customDir, err := os.Stat(setting.CustomPath) if err == nil && customDir.IsDir() { if err := z.AddDir("custom", setting.CustomPath); err != nil { log.Fatalf("Fail to include custom: %v", err) } } else { log.Printf("Custom dir %s doesn't exist, skipped", setting.CustomPath) } if err := z.AddDir("log", setting.LogRootPath); err != nil { log.Fatalf("Fail to include log: %v", err) } // FIXME: SSH key file. if err = z.Close(); err != nil { os.Remove(fileName) log.Fatalf("Fail to save %s: %v", fileName, err) } if err := os.Chmod(fileName, 0600); err != nil { log.Printf("Can't change file access permissions mask to 0600: %v", err) } log.Printf("Removing tmp work dir: %s", TmpWorkDir) os.RemoveAll(TmpWorkDir) log.Printf("Finish dumping in file %s", fileName) return nil }
func setupSpec(g *generate.Generator, context *cli.Context) error { if context.GlobalBool("host-specific") { g.HostSpecific = true } spec := g.Spec() if len(spec.Version) == 0 { g.SetVersion(rspec.Version) } if context.IsSet("hostname") { g.SetHostname(context.String("hostname")) } g.SetPlatformOS(context.String("os")) g.SetPlatformArch(context.String("arch")) if context.IsSet("label") { annotations := context.StringSlice("label") for _, s := range annotations { pair := strings.Split(s, "=") if len(pair) != 2 { return fmt.Errorf("incorrectly specified annotation: %s", s) } g.AddAnnotation(pair[0], pair[1]) } } g.SetRootPath(context.String("rootfs")) if context.IsSet("read-only") { g.SetRootReadonly(context.Bool("read-only")) } if context.IsSet("uid") { g.SetProcessUID(uint32(context.Int("uid"))) } if context.IsSet("gid") { g.SetProcessGID(uint32(context.Int("gid"))) } if context.IsSet("selinux-label") { g.SetProcessSelinuxLabel(context.String("selinux-label")) } g.SetProcessCwd(context.String("cwd")) if context.IsSet("apparmor") { g.SetProcessApparmorProfile(context.String("apparmor")) } if context.IsSet("no-new-privileges") { g.SetProcessNoNewPrivileges(context.Bool("no-new-privileges")) } if context.IsSet("tty") { g.SetProcessTerminal(context.Bool("tty")) } if context.IsSet("args") { g.SetProcessArgs(context.StringSlice("args")) } if context.IsSet("env") { envs := context.StringSlice("env") for _, env := range envs { g.AddProcessEnv(env) } } if context.IsSet("groups") { groups := context.StringSlice("groups") for _, group := range groups { groupID, err := strconv.Atoi(group) if err != nil { return err } g.AddProcessAdditionalGid(uint32(groupID)) } } if context.IsSet("cgroups-path") { g.SetLinuxCgroupsPath(context.String("cgroups-path")) } if context.IsSet("mount-label") { g.SetLinuxMountLabel(context.String("mount-label")) } if context.IsSet("sysctl") { sysctls := context.StringSlice("sysctl") for _, s := range sysctls { pair := strings.Split(s, "=") if len(pair) != 2 { return fmt.Errorf("incorrectly specified sysctl: %s", s) } g.AddLinuxSysctl(pair[0], pair[1]) } } privileged := false if context.IsSet("privileged") { privileged = context.Bool("privileged") } g.SetupPrivileged(privileged) if context.IsSet("cap-add") { addCaps := context.StringSlice("cap-add") for _, cap := range addCaps { if err := g.AddProcessCapability(cap); err != nil { return err } } } if context.IsSet("cap-drop") { dropCaps := context.StringSlice("cap-drop") for _, cap := range dropCaps { if err := g.DropProcessCapability(cap); err != nil { return err } } } needsNewUser := false var uidMaps, gidMaps []string if context.IsSet("uidmappings") { uidMaps = context.StringSlice("uidmappings") } if context.IsSet("gidmappings") { gidMaps = context.StringSlice("gidmappings") } if len(uidMaps) > 0 || len(gidMaps) > 0 { needsNewUser = true } setupLinuxNamespaces(context, g, needsNewUser) if context.IsSet("tmpfs") { tmpfsSlice := context.StringSlice("tmpfs") for _, s := range tmpfsSlice { dest, options, err := parseTmpfsMount(s) if err != nil { return err } g.AddTmpfsMount(dest, options) } } mountCgroupOption := context.String("mount-cgroups") if err := g.AddCgroupsMount(mountCgroupOption); err != nil { return err } if context.IsSet("bind") { binds := context.StringSlice("bind") for _, bind := range binds { source, dest, options, err := parseBindMount(bind) if err != nil { return err } g.AddBindMount(source, dest, options) } } if context.IsSet("prestart") { preStartHooks := context.StringSlice("prestart") for _, hook := range preStartHooks { path, args := parseHook(hook) g.AddPreStartHook(path, args) } } if context.IsSet("poststop") { postStopHooks := context.StringSlice("poststop") for _, hook := range postStopHooks { path, args := parseHook(hook) g.AddPostStopHook(path, args) } } if context.IsSet("poststart") { postStartHooks := context.StringSlice("poststart") for _, hook := range postStartHooks { path, args := parseHook(hook) g.AddPostStartHook(path, args) } } if context.IsSet("root-propagation") { rp := context.String("root-propagation") if err := g.SetLinuxRootPropagation(rp); err != nil { return err } } for _, uidMap := range uidMaps { hid, cid, size, err := parseIDMapping(uidMap) if err != nil { return err } g.AddLinuxUIDMapping(hid, cid, size) } for _, gidMap := range gidMaps { hid, cid, size, err := parseIDMapping(gidMap) if err != nil { return err } g.AddLinuxGIDMapping(hid, cid, size) } if context.IsSet("disable-oom-kill") { g.SetLinuxResourcesDisableOOMKiller(context.Bool("disable-oom-kill")) } if context.IsSet("oom-score-adj") { g.SetLinuxResourcesOOMScoreAdj(context.Int("oom-score-adj")) } if context.IsSet("linux-cpu-shares") { g.SetLinuxResourcesCPUShares(context.Uint64("linux-cpu-shares")) } if context.IsSet("linux-cpu-period") { g.SetLinuxResourcesCPUPeriod(context.Uint64("linux-cpu-period")) } if context.IsSet("linux-cpu-quota") { g.SetLinuxResourcesCPUQuota(context.Uint64("linux-cpu-quota")) } if context.IsSet("linux-realtime-runtime") { g.SetLinuxResourcesCPURealtimeRuntime(context.Uint64("linux-realtime-runtime")) } if context.IsSet("linux-realtime-period") { g.SetLinuxResourcesCPURealtimePeriod(context.Uint64("linux-realtime-period")) } if context.IsSet("linux-cpus") { g.SetLinuxResourcesCPUCpus(context.String("linux-cpus")) } if context.IsSet("linux-mems") { g.SetLinuxResourcesCPUMems(context.String("linux-mems")) } if context.IsSet("linux-mem-limit") { g.SetLinuxResourcesMemoryLimit(context.Uint64("linux-mem-limit")) } if context.IsSet("linux-mem-reservation") { g.SetLinuxResourcesMemoryReservation(context.Uint64("linux-mem-reservation")) } if context.IsSet("linux-mem-swap") { g.SetLinuxResourcesMemorySwap(context.Uint64("linux-mem-swap")) } if context.IsSet("linux-mem-kernel-limit") { g.SetLinuxResourcesMemoryKernel(context.Uint64("linux-mem-kernel-limit")) } if context.IsSet("linux-mem-kernel-tcp") { g.SetLinuxResourcesMemoryKernelTCP(context.Uint64("linux-mem-kernel-tcp")) } if context.IsSet("linux-mem-swappiness") { g.SetLinuxResourcesMemorySwappiness(context.Uint64("linux-mem-swappiness")) } if context.IsSet("linux-pids-limit") { g.SetLinuxResourcesPidsLimit(context.Int64("linux-pids-limit")) } var sd string var sa, ss []string if context.IsSet("seccomp-default") { sd = context.String("seccomp-default") } if context.IsSet("seccomp-arch") { sa = context.StringSlice("seccomp-arch") } if context.IsSet("seccomp-syscalls") { ss = context.StringSlice("seccomp-syscalls") } if sd == "" && len(sa) == 0 && len(ss) == 0 { return nil } // Set the DefaultAction of seccomp if context.IsSet("seccomp-default") { if err := g.SetLinuxSeccompDefault(sd); err != nil { return err } } // Add the additional architectures permitted to be used for system calls if context.IsSet("seccomp-arch") { for _, arch := range sa { if err := g.AddLinuxSeccompArch(arch); err != nil { return err } } } // Set syscall restrict in Seccomp if context.IsSet("seccomp-syscalls") { for _, syscall := range ss { if err := g.AddLinuxSeccompSyscall(syscall); err != nil { return err } } } if context.IsSet("seccomp-allow") { seccompAllows := context.StringSlice("seccomp-allow") for _, s := range seccompAllows { g.AddLinuxSeccompSyscallAllow(s) } } if context.IsSet("seccomp-errno") { seccompErrnos := context.StringSlice("seccomp-errno") for _, s := range seccompErrnos { g.AddLinuxSeccompSyscallErrno(s) } } return nil }
func renew(c *cli.Context) error { conf, _, client := setup(c) if len(c.GlobalStringSlice("domains")) <= 0 { logger().Fatal("Please specify at least one domain.") } domain := c.GlobalStringSlice("domains")[0] // load the cert resource from files. // We store the certificate, private key and metadata in different files // as web servers would not be able to work with a combined file. certPath := path.Join(conf.CertPath(), domain+".crt") privPath := path.Join(conf.CertPath(), domain+".key") metaPath := path.Join(conf.CertPath(), domain+".json") certBytes, err := ioutil.ReadFile(certPath) if err != nil { logger().Fatalf("Error while loading the certificate for domain %s\n\t%s", domain, err.Error()) } if c.IsSet("days") { expTime, err := acme.GetPEMCertExpiration(certBytes) if err != nil { logger().Printf("Could not get Certification expiration for domain %s", domain) } if int(expTime.Sub(time.Now()).Hours()/24.0) > c.Int("days") { return nil } } metaBytes, err := ioutil.ReadFile(metaPath) if err != nil { logger().Fatalf("Error while loading the meta data for domain %s\n\t%s", domain, err.Error()) } var certRes acme.CertificateResource err = json.Unmarshal(metaBytes, &certRes) if err != nil { logger().Fatalf("Error while marshalling the meta data for domain %s\n\t%s", domain, err.Error()) } if c.Bool("reuse-key") { keyBytes, err := ioutil.ReadFile(privPath) if err != nil { logger().Fatalf("Error while loading the private key for domain %s\n\t%s", domain, err.Error()) } certRes.PrivateKey = keyBytes } certRes.Certificate = certBytes newCert, err := client.RenewCertificate(certRes, !c.Bool("no-bundle"), c.Bool("must-staple")) if err != nil { logger().Fatalf("%s", err.Error()) } saveCertRes(newCert, conf) return nil }
func runServ(c *cli.Context) error { if c.IsSet("config") { setting.CustomConf = c.String("config") } setup("serv.log") if setting.SSH.Disabled { println("Gogs: SSH has been disabled") return nil } if len(c.Args()) < 1 { fail("Not enough arguments", "Not enough arguments") } cmd := os.Getenv("SSH_ORIGINAL_COMMAND") if len(cmd) == 0 { println("Hi there, You've successfully authenticated, but Gogs does not provide shell access.") println("If this is unexpected, please log in with password and setup Gogs under another user.") return nil } verb, args := parseCmd(cmd) repoPath := strings.ToLower(strings.Trim(args, "'")) rr := strings.SplitN(repoPath, "/", 2) if len(rr) != 2 { fail("Invalid repository path", "Invalid repository path: %v", args) } username := strings.ToLower(rr[0]) reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git")) isWiki := false if strings.HasSuffix(reponame, ".wiki") { isWiki = true reponame = reponame[:len(reponame)-5] } repoUser, err := models.GetUserByName(username) if err != nil { if models.IsErrUserNotExist(err) { fail("Repository owner does not exist", "Unregistered owner: %s", username) } fail("Internal error", "Failed to get repository owner (%s): %v", username, err) } repo, err := models.GetRepositoryByName(repoUser.ID, reponame) if err != nil { if models.IsErrRepoNotExist(err) { fail(_ACCESS_DENIED_MESSAGE, "Repository does not exist: %s/%s", repoUser.Name, reponame) } fail("Internal error", "Failed to get repository: %v", err) } requestedMode, has := allowedCommands[verb] if !has { fail("Unknown git command", "Unknown git command %s", verb) } // Prohibit push to mirror repositories. if requestedMode > models.ACCESS_MODE_READ && repo.IsMirror { fail("mirror repository is read-only", "") } // Allow anonymous clone for public repositories. var ( keyID int64 user *models.User ) if requestedMode == models.ACCESS_MODE_WRITE || repo.IsPrivate { keys := strings.Split(c.Args()[0], "-") if len(keys) != 2 { fail("Key ID format error", "Invalid key argument: %s", c.Args()[0]) } key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64()) if err != nil { fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err) } keyID = key.ID // Check deploy key or user key. if key.Type == models.KEY_TYPE_DEPLOY { if key.Mode < requestedMode { fail("Key permission denied", "Cannot push with deployment key: %d", key.ID) } // Check if this deploy key belongs to current repository. if !models.HasDeployKey(key.ID, repo.ID) { fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID) } // Update deploy key activity. deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID) if err != nil { fail("Internal error", "GetDeployKey: %v", err) } deployKey.Updated = time.Now() if err = models.UpdateDeployKey(deployKey); err != nil { fail("Internal error", "UpdateDeployKey: %v", err) } } else { user, err = models.GetUserByKeyID(key.ID) if err != nil { fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err) } mode, err := models.AccessLevel(user, repo) if err != nil { fail("Internal error", "Fail to check access: %v", err) } else if mode < requestedMode { clientMessage := _ACCESS_DENIED_MESSAGE if mode >= models.ACCESS_MODE_READ { clientMessage = "You do not have sufficient authorization for this action" } fail(clientMessage, "User %s does not have level %v access to repository %s", user.Name, requestedMode, repoPath) } } } uuid := gouuid.NewV4().String() os.Setenv("uuid", uuid) // Special handle for Windows. if setting.IsWindows { verb = strings.Replace(verb, "-", " ", 1) } var gitcmd *exec.Cmd verbs := strings.Split(verb, " ") if len(verbs) == 2 { gitcmd = exec.Command(verbs[0], verbs[1], repoPath) } else { gitcmd = exec.Command(verb, repoPath) } gitcmd.Dir = setting.RepoRootPath gitcmd.Stdout = os.Stdout gitcmd.Stdin = os.Stdin gitcmd.Stderr = os.Stderr if err = gitcmd.Run(); err != nil { fail("Internal error", "Failed to execute git command: %v", err) } if requestedMode == models.ACCESS_MODE_WRITE { handleUpdateTask(uuid, user, repoUser, reponame, isWiki) } // Update user key activity. if keyID > 0 { key, err := models.GetPublicKeyByID(keyID) if err != nil { fail("Internal error", "GetPublicKeyById: %v", err) } key.Updated = time.Now() if err = models.UpdatePublicKey(key); err != nil { fail("Internal error", "UpdatePublicKey: %v", err) } } return nil }
func manage(c *cli.Context) { var ( tlsConfig *tls.Config err error ) // If either --tls or --tlsverify are specified, load the certificates. if c.Bool("tls") || c.Bool("tlsverify") { if !c.IsSet("tlscert") || !c.IsSet("tlskey") { log.Fatal("--tlscert and --tlskey must be provided when using --tls") } if c.Bool("tlsverify") && !c.IsSet("tlscacert") { log.Fatal("--tlscacert must be provided when using --tlsverify") } tlsConfig, err = loadTLSConfig( c.String("tlscacert"), c.String("tlscert"), c.String("tlskey"), c.Bool("tlsverify")) if err != nil { log.Fatal(err) } } else { // Otherwise, if neither --tls nor --tlsverify are specified, abort if // the other flags are passed as they will be ignored. if c.IsSet("tlscert") || c.IsSet("tlskey") || c.IsSet("tlscacert") { log.Fatal("--tlscert, --tlskey and --tlscacert require the use of either --tls or --tlsverify") } } refreshMinInterval := c.Duration("engine-refresh-min-interval") refreshMaxInterval := c.Duration("engine-refresh-max-interval") if refreshMinInterval <= time.Duration(0)*time.Second { log.Fatal("min refresh interval should be a positive number") } if refreshMaxInterval < refreshMinInterval { log.Fatal("max refresh interval cannot be less than min refresh interval") } // engine-refresh-retry is deprecated refreshRetry := c.Int("engine-refresh-retry") if refreshRetry != 3 { log.Fatal("--engine-refresh-retry is deprecated. Use --engine-failure-retry") } failureRetry := c.Int("engine-failure-retry") if failureRetry <= 0 { log.Fatal("invalid failure retry count") } engineOpts := &cluster.EngineOpts{ RefreshMinInterval: refreshMinInterval, RefreshMaxInterval: refreshMaxInterval, FailureRetry: failureRetry, } uri := getDiscovery(c) if uri == "" { log.Fatalf("discovery required to manage a cluster. See '%s manage --help'.", c.App.Name) } discovery := createDiscovery(uri, c) s, err := strategy.New(c.String("strategy")) if err != nil { log.Fatal(err) } // see https://github.com/urfave/cli/issues/160 names := c.StringSlice("filter") if c.IsSet("filter") || c.IsSet("f") { names = names[DefaultFilterNumber:] } fs, err := filter.New(names) if err != nil { log.Fatal(err) } sched := scheduler.New(s, fs) var cl cluster.Cluster switch c.String("cluster-driver") { case "mesos-experimental": log.Warn("WARNING: the mesos driver is currently experimental, use at your own risks") cl, err = mesos.NewCluster(sched, tlsConfig, uri, c.StringSlice("cluster-opt"), engineOpts) case "swarm": cl, err = swarm.NewCluster(sched, tlsConfig, discovery, c.StringSlice("cluster-opt"), engineOpts) default: log.Fatalf("unsupported cluster %q", c.String("cluster-driver")) } if err != nil { log.Fatal(err) } // see https://github.com/urfave/cli/issues/160 hosts := c.StringSlice("host") if c.IsSet("host") || c.IsSet("H") { hosts = hosts[1:] } server := api.NewServer(hosts, tlsConfig) if c.Bool("replication") { addr := c.String("advertise") if addr == "" { log.Fatal("--advertise address must be provided when using --leader-election") } if !checkAddrFormat(addr) { log.Fatal("--advertise should be of the form ip:port or hostname:port") } leaderTTL, err := time.ParseDuration(c.String("replication-ttl")) if err != nil { log.Fatalf("invalid --replication-ttl: %v", err) } if leaderTTL <= time.Duration(0)*time.Second { log.Fatalf("--replication-ttl should be a positive number") } setupReplication(c, cl, server, discovery, addr, leaderTTL, tlsConfig) } else { server.SetHandler(api.NewPrimary(cl, tlsConfig, &statusHandler{cl, nil, nil}, c.GlobalBool("debug"), c.Bool("cors"))) cluster.NewWatchdog(cl) } log.Fatal(server.ListenAndServe()) }
func getProcess(context *cli.Context, bundle string) (*specs.Process, error) { if path := context.String("process"); path != "" { f, err := os.Open(path) if err != nil { return nil, err } defer f.Close() var p specs.Process if err := json.NewDecoder(f).Decode(&p); err != nil { return nil, err } return &p, validateProcessSpec(&p) } // process via cli flags if err := os.Chdir(bundle); err != nil { return nil, err } spec, err := loadSpec(specConfig) if err != nil { return nil, err } p := spec.Process p.Args = context.Args()[1:] // override the cwd, if passed if context.String("cwd") != "" { p.Cwd = context.String("cwd") } if ap := context.String("apparmor"); ap != "" { p.ApparmorProfile = ap } if l := context.String("process-label"); l != "" { p.SelinuxLabel = l } if caps := context.StringSlice("cap"); len(caps) > 0 { p.Capabilities = caps } // append the passed env variables for _, e := range context.StringSlice("env") { p.Env = append(p.Env, e) } // set the tty if context.IsSet("tty") { p.Terminal = context.Bool("tty") } if context.IsSet("no-new-privs") { p.NoNewPrivileges = context.Bool("no-new-privs") } // override the user, if passed if context.String("user") != "" { u := strings.SplitN(context.String("user"), ":", 2) if len(u) > 1 { gid, err := strconv.Atoi(u[1]) if err != nil { return nil, fmt.Errorf("parsing %s as int for gid failed: %v", u[1], err) } p.User.GID = uint32(gid) } uid, err := strconv.Atoi(u[0]) if err != nil { return nil, fmt.Errorf("parsing %s as int for uid failed: %v", u[0], err) } p.User.UID = uint32(uid) } return &p, nil }
func addSeccomp(context *cli.Context, g *generate.Generator) error { // Set the DefaultAction of seccomp if context.IsSet("seccomp-default") { seccompDefault := context.String("seccomp-default") err := g.SetDefaultSeccompAction(seccompDefault) if err != nil { return err } } else if context.IsSet("seccomp-default-force") { seccompDefaultForced := context.String("seccomp-default-force") err := g.SetDefaultSeccompActionForce(seccompDefaultForced) if err != nil { return err } } // Add the additional architectures permitted to be used for system calls if context.IsSet("seccomp-arch") { seccompArch := context.String("seccomp-arch") architectureArgs := strings.Split(seccompArch, ",") for _, arg := range architectureArgs { err := g.SetSeccompArchitecture(arg) if err != nil { return err } } } if context.IsSet("seccomp-errno") { err := seccompSet(context, "errno", g) if err != nil { return err } } if context.IsSet("seccomp-kill") { err := seccompSet(context, "kill", g) if err != nil { return err } } if context.IsSet("seccomp-trace") { err := seccompSet(context, "trace", g) if err != nil { return err } } if context.IsSet("seccomp-trap") { err := seccompSet(context, "trap", g) if err != nil { return err } } if context.IsSet("seccomp-allow") { err := seccompSet(context, "allow", g) if err != nil { return err } } if context.IsSet("seccomp-remove") { seccompRemove := context.String("seccomp-remove") err := g.RemoveSeccompRule(seccompRemove) if err != nil { return err } } if context.IsSet("seccomp-remove-all") { err := g.RemoveAllSeccompRules() if err != nil { return err } } return nil }
func setupLinuxNamespaces(context *cli.Context, g *generate.Generator, needsNewUser bool) { for _, nsName := range generate.Namespaces { if !context.IsSet(nsName) && !(needsNewUser && nsName == "user") { continue } nsPath := context.String(nsName) if nsPath == "host" { g.RemoveLinuxNamespace(nsName) continue } g.AddOrReplaceLinuxNamespace(nsName, nsPath) } }