Exemple #1
0
func SecureYamlCmd(c *cli.Context, client drone.Client) error {
	var (
		repo     = c.String("repo")
		inFile   = c.String("in")
		outFile  = c.String("out")
		ymlFile  = c.String("yaml")
		checksum = c.BoolT("checksum")
	)

	owner, name, err := parseRepo(repo)
	if err != nil {
		return err
	}

	keypair, err := client.RepoKey(owner, name)
	if err != nil {
		return err
	}

	key, err := toPublicKey(keypair.Public)
	if err != nil {
		return err
	}

	// read the .drone.sec.yml file (plain text)
	plaintext, err := readInput(inFile)
	if err != nil {
		return err
	}

	// parse the .drone.sec.yml file
	sec := new(secure.Secure)
	err = yaml.Unmarshal(plaintext, sec)
	if err != nil {
		return err
	}

	// read the .drone.yml file and caclulate the
	// checksum. add to the .drone.sec.yml file.
	yml, err := ioutil.ReadFile(ymlFile)
	if err == nil && checksum {
		sec.Checksum = sha256sum(string(yml))
	}

	// re-marshal the .drone.sec.yml file since we've
	// added the checksum
	plaintext, err = yaml.Marshal(sec)
	if err != nil {
		return err
	}

	// encrypt the .drone.sec.yml file
	ciphertext, err := encrypt(plaintext, key)
	if err != nil {
		return err
	}

	// write the encrypted .drone.sec.yml file to .drone.sec
	return writeOutput(outFile, ciphertext)
}
Exemple #2
0
func serve(c *cli.Context) {
	// Ensure api socket directory exists; if not, create it
	apiSocket := getApiSocket(c)
	if _, err := os.Stat(apiSocket); os.IsNotExist(err) {
		os.MkdirAll(path.Dir(apiSocket), 0777)
	}

	d := dokku.New()

	// If caching is enabled, create cache socket if necessary and launch cache
	// server in the background
	if !c.BoolT("enable-cache") {
		cacheSocket := getCacheSocket(c)
		if _, err := os.Stat(cacheSocket); os.IsNotExist(err) {
			os.MkdirAll(path.Dir(cacheSocket), 0777)
		}

		go func() {
			err := listenCache(d, cacheSocket)
			if err != nil {
				panic(err)
			}
		}()
	}

	// Start api server
	err := listenAPI(d, apiSocket)
	if err != nil {
		panic(err)
	}
}
Exemple #3
0
// Migrate runs migrations
func Migrate(ctx *cli.Context) {
	if ctx.BoolT("d") {
		// run migrations
		migration.DropTables()
	}
	migration.MigrateTables()
	query.PopulateDB()
}
Exemple #4
0
// helper function to setup the GitHub remote from the CLI arguments.
func setupGithub(c *cli.Context) (remote.Remote, error) {
	return github.New(github.Opts{
		URL:         c.String("github-server"),
		Client:      c.String("github-client"),
		Secret:      c.String("github-sercret"),
		Scopes:      c.StringSlice("github-scope"),
		Username:    c.String("github-git-username"),
		Password:    c.String("github-git-password"),
		PrivateMode: c.Bool("github-private-mode"),
		SkipVerify:  c.Bool("github-skip-verify"),
		MergeRef:    c.BoolT("github-merge-ref"),
	})
}
Exemple #5
0
func cmdLogsStream(c *cli.Context) {
	_, app, err := stdcli.DirApp(c, ".")

	if err != nil {
		stdcli.Error(err)
		return
	}

	err = rackClient(c).StreamAppLogs(app, c.String("filter"), c.BoolT("follow"), c.Duration("since"), os.Stdout)

	if err != nil {
		stdcli.Error(err)
		return
	}
}
Exemple #6
0
func getOptions(c *cli.Context) ([]magpie.Option, error) {
	var options []magpie.Option
	if c.IsSet(tagFlag) {
		options = append(options, magpie.Tags(c.StringSlice(tagFlag)))
	}
	if c.IsSet(prefixFlag) {
		options = append(options, magpie.Prefix(c.String(prefixFlag)))
	}
	if c.IsSet(packageNameFlag) {
		options = append(options, magpie.PackageName(c.String(packageNameFlag)))
	}
	if c.IsSet(unsafeFlag) {
		options = append(options, magpie.Unsafe(c.Bool(unsafeFlag)))
	}
	if c.IsSet(compressFlag) {
		options = append(options, magpie.Compress(c.BoolT(compressFlag)))
	}
	if c.IsSet(fileModeFlag) {
		fileMode := c.String(fileModeFlag)
		if fileMode != "" {
			n, err := strconv.ParseUint(fileMode, 10, 32)
			if err != nil {
				return nil, err
			}
			options = append(options, magpie.OverrideFileMode(uint(n)))
		}
	}
	if c.IsSet(fileModTimeFlag) {
		fileMod := c.String(fileModTimeFlag)
		if fileMod != "" {
			n, err := strconv.ParseInt(fileMod, 10, 64)
			if err != nil {
				return nil, err
			}
			options = append(options, magpie.OverrideFileModTime(n))
		}
	}
	if c.IsSet(outputFlag) {
		options = append(options, magpie.OutputFile(c.String(outputFlag)))
	}
	if c.IsSet(ignoreFlag) {
		options = append(options, magpie.Ignore(c.StringSlice(ignoreFlag)))
	}
	return options, nil
}
Exemple #7
0
func server(ctx *cli.Context) {
	cfgFile := configName
	if first := ctx.Args().First(); first != "" {
		cfgFile = first
	}

	cfg, err := getConfig(cfgFile)
	if err != nil {
		fmt.Println(err)
		return
	}
	s := hero.NewServer(cfg, &hero.SimpleTokenGen{}, nil)

	if ctx.BoolT("migrate") {
		s.Migrate()
	}
	s.Run()
}
Exemple #8
0
func create(c *cli.Context) {
	checkArgs(c)

	d := dogo.Droplet{
		Name:          c.Args().First(),
		ImageID:       c.Int("image"),
		SizeID:        dogo.SizesMap[c.String("size")],
		RegionID:      dogo.RegionsMap[c.String("region")],
		BackupsActive: c.BoolT("backups"),
	}
	keys := c.IntSlice("keys")
	network := c.BoolT("network")

	_, err := docli.CreateDroplet(d, keys, network)
	if err != nil {
		fatalf(err.Error())
	}
	fmt.Printf("Successfully queued %s for creation ... \n", d.Name)
}
Exemple #9
0
func clirun(c *cli.Context) {
	config := &Config{
		Dest: c.String("dest"),
		Name: c.String("name"),

		Data:       make(map[string]string),
		OpenEditor: c.BoolT("open-editor"),
	}

	src := c.String("src")
	if len(src) > 0 {
		config.Source = &DirectorySource{Path: src}
	} else {
		config.Source = &GithubReleaseSource{
			Tag:   c.String("gh-tag"),
			Owner: c.String("gh-owner"),
			Repo:  c.String("gh-repo"),
			Name:  c.String("skel"),
		}
	}

	data := c.String("data")
	if len(data) > 0 {
		info, err := os.Stat(data)
		if err != nil || info.IsDir() {
			log.Printf("Couldn't open %s. Skipping.\n", data)
		} else {
			content, err := ioutil.ReadFile(data)
			if err != nil {
				log.Printf("Failed to read data file. Skipping. Error was: %s\n", err)
			}
			err = yaml.Unmarshal(content, &config.Data)
			if err != nil {
				log.Printf("Failed to unmarshall data file: %s.\n", err)
			}
		}
	}

	if err := Run(config); err != nil {
		log.Fatal(err)
	}
}
Exemple #10
0
func LoadConfig(ctx *cli.Context) {
	var contents []byte

	if _, err := os.Stat(CONFIG_FILE); err != nil && CONFIG_FILE != "/dev/null" {
		fmt.Printf("Unable to find config file. Resorting to defaults.\n")
	} else {
		contents = handle_err(ioutil.ReadFile(CONFIG_FILE)).([]byte)
		err := json.Unmarshal(contents, &RC)
		if err != nil && CONFIG_FILE != "/dev/null" {
			fmt.Printf("Error reading config file (%s): %v.\n", CONFIG_FILE, err)
		}
	}

	// Override config file values with CLI options

	if &RC.Host == nil || ctx.IsSet("host") {
		RC.Host = ctx.String("host")
	}

	if &RC.Port == nil || ctx.IsSet("port") {
		RC.Port = ctx.Int("port")
	}

	if &RC.Nick == nil || ctx.IsSet("nick") {
		RC.Nick = ctx.String("nick")
	}

	if &RC.Channel == nil || ctx.IsSet("channel") {
		RC.Channel = ctx.String("channel")
	}

	if &RC.SSL == nil {
		RC.SSL = ctx.BoolT("insecure")
	}

	if &RC.Verbose == nil {
		RC.Verbose = ctx.Bool("verbose")
	}

	RC.VTClient = govt.Client{Apikey: RC.VTAPIKey, Url: "https://www.virustotal.com/vtapi/v2/"}
}
Exemple #11
0
func doAlertsList(c *cli.Context) error {
	conffile := c.GlobalString("conf")
	filterServices := c.StringSlice("service")
	filterStatuses := c.StringSlice("host-status")
	client := newMackerel(conffile)

	alerts, err := client.FindAlerts()
	logger.DieIf(err)
	joinedAlerts := joinMonitorsAndHosts(client, alerts)

	for _, joinAlert := range joinedAlerts {
		if len(filterServices) > 0 {
			found := false
			for _, filterService := range filterServices {
				if joinAlert.Host != nil {
					if _, ok := joinAlert.Host.Roles[filterService]; ok {
						found = true
					}
				} else if joinAlert.Monitor.Service == filterService {
					found = true
				}
			}
			if !found {
				continue
			}
		}
		if len(filterStatuses) > 0 {
			found := false
			for _, filterStatus := range filterStatuses {
				if joinAlert.Host != nil && joinAlert.Host.Status == filterStatus {
					found = true
				}
			}
			if !found {
				continue
			}
		}
		fmt.Println(formatJoinedAlert(joinAlert, c.BoolT("color")))
	}
	return nil
}
Exemple #12
0
func AddAttachment(c *cli.Context) {
	objectId := helper.ValidId(c.Args().First())
	attachmentPath := c.Args().Get(1)

	object, err := data.GetObject(objectId)
	helper.ErrExit(err != nil, fmt.Sprintf("Invalid object ID %s!\n", objectId))

	dbFile, err := data.Files().Create("")
	helper.ErrPanic(err)

	file, err := os.Open(attachmentPath)
	helper.ErrPanic(err)
	defer file.Close()

	_, err = io.Copy(dbFile, file)
	helper.ErrPanic(err)

	err = dbFile.Close()
	helper.ErrPanic(err)

	var (
		content  = ""
		metadata = make(map[string]string)
	)

	if strings.ToLower(filepath.Ext(file.Name())) == ".pdf" {
		if c.BoolT("extract-pdf-text") {
			content, metadata, err = helper.ConvertPDF(file)
			helper.ErrPanic(err)
		}
	}

	attachment := data.CreateAttachment(dbFile, path.Base(attachmentPath), content, metadata)
	object.Attachments = append(object.Attachments, *attachment)
	object.Update()

	fmt.Println(attachment.Id.Hex())
}
Exemple #13
0
func loadConfig(c *cli.Context) {
	if len(c.Args()) > 0 {
		config_path := c.Args()[0]
		_, err := toml.DecodeFile(config_path, &Config)
		checkErr(err)
		log.Printf("loaded configuration from %s %+v\n", config_path, Config)
	}

	if c.IsSet("db-log") == true {
		Config.DBLog = c.Bool("db-log")
	}

	if c.IsSet("development") == true {
		Config.Development = c.BoolT("development")
	}

	if c.IsSet("database") == true {
		Config.DBPath = c.String("database")
	}

	if c.IsSet("port") == true {
		Config.Port = c.Int("port")
	}
}
Exemple #14
0
// New TODO
func New(context *cli.Context) *Config {

	// TODO: parse this more gracefully
	loggingLevel := logrus.DebugLevel
	logLevelArg := context.String(logLevel)
	var err error
	loggingLevel, err = logrus.ParseLevel(logLevelArg)
	if err != nil {
		loggingLevel = logrus.DebugLevel
	}

	return &Config{
		ServiceName:    context.String(serviceName),
		ServiceVerion:  context.String(serviceVersion),
		EndpointHost:   context.String(endpointHost),
		EndpointPort:   context.Int(endpointPort),
		LogstashServer: context.String(logstashServer),
		Register:       context.BoolT(register),
		Proxy:          context.BoolT(proxy),
		Log:            context.BoolT(log),
		Supervise:      context.Bool(supervise),
		Controller: Controller{
			URL:  context.String(controllerURL),
			Poll: context.Duration(controllerPoll),
		},
		Tenant: Tenant{
			ID:        context.String(tenantID),
			Token:     context.String(tenantToken),
			TTL:       context.Duration(tenantTTL),
			Heartbeat: context.Duration(tenantHeartbeat),
		},
		Registry: Registry{
			URL:   context.String(registryURL),
			Token: context.String(registryToken),
		},
		Kafka: Kafka{
			Username: context.String(kafkaUsername),
			Password: context.String(kafkaPassword),
			APIKey:   context.String(kafkaToken),
			RestURL:  context.String(kafkaRestURL),
			Brokers:  context.StringSlice(kafkaBrokers),
			SASL:     context.Bool(kafkaSASL),
		},
		Nginx: Nginx{
			Port: context.Int(nginxPort),
		},
		LogLevel: loggingLevel,
		AppArgs:  context.Args(),
	}
}
Exemple #15
0
func server(ctx *cli.Context) {
	cfgFile := configName
	if first := ctx.Args().First(); first != "" {
		cfgFile = first
	}

	cfg, err := getConfig(cfgFile)
	if err != nil {
		fmt.Println(err)
		return
	}
	s := hero.NewServer(cfg, &hero.SimpleTokenGen{}, nil)

	if ctx.BoolT("dev") {
		v, err := hero.NewDefaultView(cfg.TemplatesDir, true)
		if err != nil {
			fmt.Println(err)
			return
		}
		s = hero.NewServer(cfg, &hero.SimpleTokenGen{}, v)
	}
	if ctx.BoolT("migrate") {
		s.Migrate()
	}
	if ctx.BoolT("https") {
		cert := ctx.String("cert")
		_, ferr := os.Stat(cert)
		if ferr != nil {
			fmt.Println(ferr)
			return
		}
		key := ctx.String("key")
		_, ferr = os.Stat(cert)
		if ferr != nil {
			fmt.Println(ferr)
			return
		}
		s.RunTLS(cert, key)
		return
	}

	s.Run()
}
Exemple #16
0
func pinCommand(ctx *cli.Context) {
	initLogs(ctx)

	var (
		vars   template.Vars
		data   []byte
		output = ctx.String("output")
		format = ctx.String("type")
		local  = ctx.BoolT("local")
		hub    = ctx.BoolT("hub")
		fd     = os.Stdout
	)

	if output == "-" && !ctx.GlobalIsSet("verbose") {
		log.SetLevel(log.WarnLevel)
	}

	dockerCli := initDockerClient(ctx)
	config := initComposeConfig(ctx, dockerCli)
	auth := initAuthConfig(ctx)

	compose, err := compose.New(&compose.Config{
		Manifest: config,
		Docker:   dockerCli,
		Auth:     auth,
	})
	if err != nil {
		log.Fatal(err)
	}

	if vars, err = compose.PinAction(local, hub); err != nil {
		log.Fatal(err)
	}

	if output != "-" {
		if fd, err = os.Create(output); err != nil {
			log.Fatal(err)
		}
		defer fd.Close()

		if ext := filepath.Ext(output); !ctx.IsSet("type") && ext == ".json" {
			format = "json"
		}
	}

	switch format {
	case "yaml":
		if data, err = yaml.Marshal(vars); err != nil {
			log.Fatal(err)
		}
	case "json":
		if data, err = json.Marshal(vars); err != nil {
			log.Fatal(err)
		}
	default:
		log.Fatalf("Possible tyoes are `yaml` and `json`, unknown type `%s`", format)
	}

	if _, err := io.Copy(fd, bytes.NewReader(data)); err != nil {
		log.Fatal(err)
	}
}
Exemple #17
0
func defaultAction(c *cli.Context) {
	thisCfg := new(AppCfg)
	thisCfg.Lines = c.Int("lines")
	thisCfg.Fail = c.Bool("fail")
	thisCfg.Color = c.BoolT("color")

	// If no flag, get current username
	u := c.String("user")
	if len(u) == 0 {
		usr, err := user.Current()
		if err == nil {
			u = usr.Username
		}
	}

	// Load SSH keys
	auths, err := getKeyAuths(c.GlobalStringSlice("key")...)
	if err != nil {
		log.Error("Error loading key", err)
	}

	if len(auths) == 0 {
		log.Error("No keys defined, cannot continue!", nil)
		cli.ShowAppHelp(c)
		os.Exit(2)
	}

	for _, target := range c.StringSlice("server") {
		thisHost := &HostConfig{
			User:  u,
			Auths: auths,
			Addr:  portAddrCheck(target),
		}
		thisCfg.Hosts = append(thisCfg.Hosts, thisHost)
	}

	// host(s) is required
	if len(thisCfg.Hosts) == 0 {
		log.Error("At least one host is required", nil)
		cli.ShowAppHelp(c)
		os.Exit(2)
	}

	// At least one command is required
	if len(c.Args().First()) == 0 {
		log.Error("At least one command is required", nil)
		cli.ShowAppHelp(c)
		os.Exit(2)
	}
	// append list of commands to argList
	thisCfg.Cmds = append([]string{c.Args().First()}, c.Args().Tail()...)
	done := make(chan bool, len(thisCfg.Hosts))

	for _, h := range thisCfg.Hosts {
		go handleHost(h, thisCfg.Cmds, thisCfg.Color, thisCfg.Lines, thisCfg.Fail, done)
	}

	// Drain chan before exiting
	for i := 0; i < len(thisCfg.Hosts); i++ {
		<-done
	}
}
func getCert(c *cli.Context) {

	configPath := c.String("config-file")
	environment := c.String("environment")
	certRequestID := c.Args().First()

	allConfig := make(map[string]ssh_ca_util.RequesterConfig)
	err := ssh_ca_util.LoadConfig(configPath, &allConfig)
	wrongTypeConfig, err := ssh_ca_util.GetConfigForEnv(environment, &allConfig)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	config := wrongTypeConfig.(ssh_ca_util.RequesterConfig)

	getResp, err := http.Get(config.SignerUrl + "cert/requests/" + certRequestID)
	if err != nil {
		fmt.Println("Didn't get a valid response", err)
		os.Exit(1)
	}
	getRespBuf, err := ioutil.ReadAll(getResp.Body)
	if err != nil {
		fmt.Println("Error reading response body", err)
		os.Exit(1)
	}
	getResp.Body.Close()
	if getResp.StatusCode != 200 {
		fmt.Println("Error getting that request id:", string(getRespBuf))
		os.Exit(1)
	}

	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(getRespBuf)
	if err != nil {
		fmt.Println("Trouble parsing response", err)
		os.Exit(1)
	}
	cert := pubKey.(*ssh.Certificate)
	secondsRemaining := int64(cert.ValidBefore) - int64(time.Now().Unix())
	if secondsRemaining < 1 {
		fmt.Println("This certificate has already expired.")
		os.Exit(1)
	}

	pubKeyPath, err := findKeyLocally(cert.Key)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	pubKeyPath = strings.Replace(pubKeyPath, ".pub", "-cert.pub", 1)
	err = ioutil.WriteFile(pubKeyPath, getRespBuf, 0644)
	if err != nil {
		fmt.Printf("Couldn't write certificate file to %s: %s\n", pubKeyPath, err)
	}

	ssh_ca_util.PrintForInspection(*cert)
	if c.BoolT("add-key") {
		privKeyPath := strings.Replace(pubKeyPath, "-cert.pub", "", 1)
		cmd := exec.Command("ssh-add", "-t", fmt.Sprintf("%d", secondsRemaining), privKeyPath)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Stdin = os.Stdin
		err = cmd.Run()
		if err != nil {
			fmt.Println("Error in ssh-add")
			os.Exit(1)
		}
	}
}
Exemple #19
0
func (b *base) listGo(ctx *cli.Context) {
	if ctx.BoolT("i") {
		writeLn("list")
	}
}
Exemple #20
0
// New TODO
func New(context *cli.Context) *Config {

	// TODO: parse this more gracefully
	loggingLevel := logrus.DebugLevel
	logLevelArg := context.String(logLevel)
	var err error
	loggingLevel, err = logrus.ParseLevel(logLevelArg)
	if err != nil {
		loggingLevel = logrus.DebugLevel
	}

	endpointHost := context.String(endpointHost)
	if endpointHost == "" {
		for {
			endpointHost = LocalIP()
			if endpointHost != "" {
				break
			}
			logrus.Warn("Could not obtain local IP")
			time.Sleep(time.Second * 10)
		}
	}

	var name string
	var version string

	i := strings.Index(context.String(serviceName), ":")
	if i == -1 {
		name = context.String(serviceName)
	} else {
		name = context.String(serviceName)[:i]
		version = context.String(serviceName)[i+1:]
	}

	return &Config{
		ServiceName:    name,
		ServiceVersion: version,
		EndpointHost:   endpointHost,
		EndpointPort:   context.Int(endpointPort),
		EndpointType:   context.String(endpointType),
		LogstashServer: context.String(logstashServer),
		Register:       context.BoolT(register),
		Proxy:          context.BoolT(proxy),
		Log:            context.BoolT(log),
		Supervise:      context.Bool(supervise),
		Controller: Controller{
			URL:  context.String(controllerURL),
			Poll: context.Duration(controllerPoll),
		},
		Tenant: Tenant{
			Token:     context.String(tenantToken),
			TTL:       context.Duration(tenantTTL),
			Heartbeat: context.Duration(tenantHeartbeat),
		},
		Registry: Registry{
			URL:   context.String(registryURL),
			Token: context.String(registryToken),
		},
		Kafka: Kafka{
			Username: context.String(kafkaUsername),
			Password: context.String(kafkaPassword),
			APIKey:   context.String(kafkaToken),
			RestURL:  context.String(kafkaRestURL),
			Brokers:  context.StringSlice(kafkaBrokers),
			SASL:     context.Bool(kafkaSASL),
		},
		Nginx: Nginx{
			Port: context.Int(nginxPort),
		},
		LogLevel:    loggingLevel,
		AppArgs:     context.Args(),
		ForceUpdate: context.Bool(forceUpdate),
	}
}
Exemple #21
0
func start(c *cli.Context) {

	// debug level if requested by user
	if c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	} else {
		logrus.SetLevel(logrus.WarnLevel)
	}

	var accessToken string
	if c.String("drone-secret") != "" {
		secretToken := c.String("drone-secret")
		accessToken, _ = token.New(token.AgentToken, "").Sign(secretToken)
	} else {
		accessToken = c.String("drone-token")
	}

	logrus.Infof("Connecting to %s with token %s",
		c.String("drone-server"),
		accessToken,
	)

	client := client.NewClientToken(
		c.String("drone-server"),
		accessToken,
	)

	tls, err := dockerclient.TLSConfigFromCertPath(c.String("docker-cert-path"))
	if err == nil {
		tls.InsecureSkipVerify = c.Bool("docker-tls-verify")
	}
	docker, err := dockerclient.NewDockerClient(c.String("docker-host"), tls)
	if err != nil {
		logrus.Fatal(err)
	}

	go func() {
		for {
			if err := client.Ping(); err != nil {
				logrus.Warnf("unable to ping the server. %s", err.Error())
			}
			time.Sleep(c.Duration("ping"))
		}
	}()

	var wg sync.WaitGroup
	for i := 0; i < c.Int("docker-max-procs"); i++ {
		wg.Add(1)
		go func() {
			r := pipeline{
				drone:  client,
				docker: docker,
				config: config{
					platform:   c.String("docker-os") + "/" + c.String("docker-arch"),
					timeout:    c.Duration("timeout"),
					namespace:  c.String("namespace"),
					privileged: c.StringSlice("privileged"),
					pull:       c.BoolT("pull"),
					logs:       int64(c.Int("max-log-size")) * 1000000,
				},
			}
			for {
				if err := r.run(); err != nil {
					dur := c.Duration("backoff")
					logrus.Warnf("reconnect in %v. %s", dur, err.Error())
					time.Sleep(dur)
				}
			}
		}()
	}
	handleSignals()
	wg.Wait()
}
Exemple #22
0
func exec(c *cli.Context) error {
	sigterm := make(chan os.Signal, 1)
	cancelc := make(chan bool, 1)
	signal.Notify(sigterm, os.Interrupt)
	go func() {
		<-sigterm
		cancelc <- true
	}()

	path := c.Args().First()
	if path == "" {
		path = ".drone.yml"
	}
	path, _ = filepath.Abs(path)
	dir := filepath.Dir(path)

	file, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}

	engine, err := docker.New(
		c.String("docker-host"),
		c.String("docker-cert-path"),
		c.Bool("docker-tls-verify"),
	)
	if err != nil {
		return err
	}

	a := agent.Agent{
		Update:    agent.NoopUpdateFunc,
		Logger:    agent.TermLoggerFunc,
		Engine:    engine,
		Timeout:   c.Duration("timeout.inactivity"),
		Platform:  "linux/amd64",
		Namespace: c.String("namespace"),
		Disable:   c.StringSlice("plugin"),
		Escalate:  c.StringSlice("privileged"),
		Netrc:     []string{},
		Local:     dir,
		Pull:      c.Bool("pull"),
	}

	payload := &model.Work{
		Yaml:     string(file),
		Verified: c.BoolT("yaml.verified"),
		Signed:   c.BoolT("yaml.signed"),
		Repo: &model.Repo{
			FullName:  c.String("repo.fullname"),
			Owner:     c.String("repo.owner"),
			Name:      c.String("repo.name"),
			Kind:      c.String("repo.type"),
			Link:      c.String("repo.link"),
			Branch:    c.String("repo.branch"),
			Avatar:    c.String("repo.avatar"),
			Timeout:   int64(c.Duration("timeout").Minutes()),
			IsPrivate: c.Bool("repo.private"),
			IsTrusted: c.Bool("repo.trusted"),
			Clone:     c.String("remote.url"),
		},
		System: &model.System{
			Link: c.GlobalString("server"),
		},
		Secrets: getSecrets(c),
		Netrc: &model.Netrc{
			Login:    c.String("netrc.username"),
			Password: c.String("netrc.password"),
			Machine:  c.String("netrc.machine"),
		},
		Build: &model.Build{
			Commit:  c.String("commit.sha"),
			Branch:  c.String("commit.branch"),
			Ref:     c.String("commit.ref"),
			Link:    c.String("commit.link"),
			Message: c.String("commit.message"),
			Author:  c.String("commit.author.name"),
			Email:   c.String("commit.author.email"),
			Avatar:  c.String("commit.author.avatar"),
			Number:  c.Int("build.number"),
			Event:   c.String("build.event"),
			Deploy:  c.String("build.deploy"),
		},
		BuildLast: &model.Build{
			Number: c.Int("prev.build.number"),
			Status: c.String("prev.build.status"),
			Commit: c.String("prev.commit.sha"),
		},
	}

	if len(c.StringSlice("matrix")) > 0 {
		p := *payload
		p.Job = &model.Job{
			Environment: getMatrix(c),
		}
		return a.Run(&p, cancelc)
	}

	axes, err := yaml.ParseMatrix(file)
	if err != nil {
		return err
	}

	if len(axes) == 0 {
		axes = append(axes, yaml.Axis{})
	}

	var jobs []*model.Job
	count := 0
	for _, axis := range axes {
		jobs = append(jobs, &model.Job{
			Number:      count,
			Environment: axis,
		})
		count++
	}

	for _, job := range jobs {
		fmt.Printf("Running Matrix job #%d\n", job.Number)
		p := *payload
		p.Job = job
		if err := a.Run(&p, cancelc); err != nil {
			return err
		}
	}

	return nil
}
Exemple #23
0
func start(c *cli.Context) {

	log := redlog.New(os.Stderr)
	log.SetLevel(0)
	logger.SetLogger(log)

	// debug level if requested by user
	if c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)

		log.SetLevel(1)
	} else {
		logrus.SetLevel(logrus.WarnLevel)
	}

	var accessToken string
	if c.String("drone-secret") != "" {
		// secretToken := c.String("drone-secret")
		accessToken = c.String("drone-secret")
		// accessToken, _ = token.New(token.AgentToken, "").Sign(secretToken)
	} else {
		accessToken = c.String("drone-token")
	}

	logger.Noticef("connecting to server %s", c.String("drone-server"))

	server := strings.TrimRight(c.String("drone-server"), "/")

	tls, err := dockerclient.TLSConfigFromCertPath(c.String("docker-cert-path"))
	if err == nil {
		tls.InsecureSkipVerify = c.Bool("docker-tls-verify")
	}
	docker, err := dockerclient.NewDockerClient(c.String("docker-host"), tls)
	if err != nil {
		logrus.Fatal(err)
	}

	var client *stomp.Client

	handler := func(m *stomp.Message) {
		running.Add(1)
		defer func() {
			running.Done()
			client.Ack(m.Ack)
		}()

		r := pipeline{
			drone:  client,
			docker: docker,
			config: config{
				platform:   c.String("docker-os") + "/" + c.String("docker-arch"),
				timeout:    c.Duration("timeout"),
				namespace:  c.String("namespace"),
				privileged: c.StringSlice("privileged"),
				pull:       c.BoolT("pull"),
				logs:       int64(c.Int("max-log-size")) * 1000000,
			},
		}

		work := new(model.Work)
		m.Unmarshal(work)
		r.run(work)
	}

	handleSignals()

	backoff := c.Duration("backoff")

	for {
		// dial the drone server to establish a TCP connection.
		client, err = stomp.Dial(server)
		if err != nil {
			logger.Warningf("connection failed, retry in %v. %s", backoff, err)
			<-time.After(backoff)
			continue
		}
		opts := []stomp.MessageOption{
			stomp.WithCredentials("x-token", accessToken),
		}

		// initialize the stomp session and authenticate.
		if err = client.Connect(opts...); err != nil {
			logger.Warningf("session failed, retry in %v. %s", backoff, err)
			<-time.After(backoff)
			continue
		}

		opts = []stomp.MessageOption{
			stomp.WithAck("client"),
			stomp.WithPrefetch(
				c.Int("docker-max-procs"),
			),
		}
		if filter := c.String("filter"); filter != "" {
			opts = append(opts, stomp.WithSelector(filter))
		}

		// subscribe to the pending build queue.
		client.Subscribe("/queue/pending", stomp.HandlerFunc(func(m *stomp.Message) {
			go handler(m) // HACK until we a channel based Subscribe implementation
		}), opts...)

		logger.Noticef("connection established, ready to process builds.")
		<-client.Done()

		logger.Warningf("connection interrupted, attempting to reconnect.")
	}
}