func ParseCommand(command string) ([]string, error) { args, err := shlex.Split(command) if err != nil { return []string{}, err } return args, err }
func parseCommand(dir, command string) (string, []string, error) { args, err := shlex.Split(command) if err != nil { return "", nil, err } if len(args) == 0 { return "", nil, fmt.Errorf("invalid command %q", command) } exe, err := exec.LookPath(args[0]) if err != nil { return "", nil, err } out := []string{} for _, arg := range args[1:] { if strings.Contains(arg, "*") { pattern := filepath.Join(dir, arg) globbed, err := filepath.Glob(pattern) if err != nil { return "", nil, err } for i, g := range globbed { if strings.HasPrefix(g, dir+"/") { globbed[i] = g[len(dir)+1:] } } out = append(out, globbed...) } else { out = append(out, arg) } } return exe, out, nil }
// ExecShlex parse the command with shlex before returning an ExecCmd. // func (l *Log) ExecShlex(command string, args ...string) (*exec.Cmd, error) { cmds, e := shlex.Split(command) if l.Err(e, "parse command args", command) { return nil, e } command = cmds[0] args = append(cmds[1:], args...) l.Debug("launch", command, args) return l.ExecCmd(command, args...), nil }
func (r *Exec) Command(line string) (*exec.Cmd, error) { ss, err := shlex.Split(line) if err != nil { return nil, err } if len(ss) == 0 { return nil, errors.New("No command defined") } return exec.Command(ss[0], ss[1:]...), nil }
// InitEnv parses our data into our config func (s *ShellStep) InitEnv(env *util.Environment) { if code, ok := s.data["code"]; ok { s.Code = code } if cmd, ok := s.data["cmd"]; ok { parts, err := shlex.Split(cmd) if err == nil { s.Cmd = parts } } else { s.Cmd = []string{"/bin/bash"} } s.env = env }
// deriveLabelValue runs a command and returns its output. // It returns the empty string on error; we assume it's better to keep the set of labels constant on failure. func deriveLabelValue(cmd string) string { parts, err := shlex.Split(cmd) if err != nil { panic(fmt.Sprintf("Invalid custom metric command [%s]: %s", cmd, err)) } log.Debug("Running custom label command: %s", cmd) b, err := exec.Command(parts[0], parts[1:]...).Output() log.Debug("Got output: %s", b) if err != nil { panic(fmt.Sprintf("Custom metric command [%s] failed: %s", cmd, err)) } value := strings.TrimSpace(string(b)) if strings.Contains(value, "\n") { panic(fmt.Sprintf("Return value of custom metric command [%s] contains spaces: %s", cmd, value)) } return value }
func (c *adapter) scpExec(args string, in io.Reader, out io.Writer) error { opts, rest := scpOptions(args) // remove the quoting that ansible added to rest for shell safety. shargs, err := shlex.Split(rest) if err != nil { return err } rest = strings.Join(shargs, "") if i := bytes.IndexByte(opts, 't'); i >= 0 { return scpUploadSession(opts, rest, in, out, c.comm) } if i := bytes.IndexByte(opts, 'f'); i >= 0 { return scpDownloadSession(opts, rest, in, out, c.comm) } return errors.New("no scp mode specified") }
func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "> ", HistoryFile: "/tmp/flagly-shell.readline", }) if err != nil { println(err.Error()) os.Exit(1) } defer rl.Close() var p Program fset, err := flagly.Compile("", &p) if err != nil { println(err.Error()) os.Exit(1) } rl.Config.AutoComplete = &readline.SegmentComplete{fset.Completer()} for { line, err := rl.Readline() if err != nil { break } if line == "" { continue } command, err := shlex.Split(line) if err != nil { println("error: " + err.Error()) continue } if err := fset.Run(command); err != nil { println(err.Error()) } } }
func serviceRedeploy(args Redeploy) { // Parse volumes if len(redeployVolume) > 0 { args.Volumes = make(map[string]VolumeConfig) } // Parse command if redeployCommand != "" { command, err := shlex.Split(redeployCommand) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerCommand = command } // Parse Entrypoint if redeployEntrypoint != "" { entrypoint, err := shlex.Split(redeployEntrypoint) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerEntrypoint = entrypoint } for _, vol := range redeployVolume { t := strings.Split(vol, ":") if len(t) == 2 { args.Volumes[t[0]] = VolumeConfig{Size: t[1]} } else if len(t) == 1 { args.Volumes[t[0]] = VolumeConfig{Size: "10"} } else { fmt.Fprintf(os.Stderr, "Error: Volume parameter '%s' not formated correctly\n", vol) os.Exit(1) } } // Parse links if len(redeployLink) > 0 { args.Links = make(map[string]string) } for _, link := range redeployLink { t := strings.Split(link, ":") if len(t) == 1 { args.Links[t[0]] = t[0] } else { args.Links[t[0]] = t[1] } } // Parse ContainerNetworks arguments if len(redeployNetwork) > 0 { args.ContainerNetwork = make(map[string]map[string][]string) } for _, network := range redeployNetwork { args.ContainerNetwork[network] = make(map[string][]string) } for _, gat := range redeployGateway { t := strings.Split(gat, ":") if len(t) != 2 { fmt.Fprintf(os.Stderr, "Invalid gateway parameter, should be \"input:output\". Typically, output will be 'predictor' or 'public'") os.Exit(1) } } // Load Pool args.Pool = redeployPool // Parse ContainerPorts args.ContainerPorts = parsePublishedPort(redeployPublished) app := args.Application service := args.Service path := fmt.Sprintf("/applications/%s/services/%s/redeploy", app, service) body, err := json.MarshalIndent(args, " ", " ") if err != nil { fmt.Fprintf(os.Stderr, "Fatal: %s\n", err) return } // Attach console if !redeployBatch { internal.StreamPrint("GET", fmt.Sprintf("/applications/%s/services/%s/attach", app, service), nil) } // Redeploy buffer, _, err := internal.Stream("POST", path+"?stream", body) if err != nil { fmt.Fprintf(os.Stderr, "Error: %s\n", err) os.Exit(1) } line, err := internal.DisplayStream(buffer) internal.Check(err) if line != nil { var data map[string]interface{} err = json.Unmarshal(line, &data) internal.Check(err) fmt.Printf("Hostname: %v\n", data["hostname"]) fmt.Printf("Running containers: %v/%v\n", data["container_number"], data["container_target"]) } if !redeployBatch { internal.ExitAfterCtrlC() } }
"github.com/google/shlex" "github.com/tftp-go-team/libgotftp/src" ) // Borrowed from Ruby // https://github.com/ruby/ruby/blob/v1_9_3_429/lib/shellwords.rb#L82 var shellEscape = regexp.MustCompile("([^A-Za-z0-9_\\-.,:\\/@\n])") var ShellHook = HookComponents{ func(command string, request tftp.Request) (*HookResult, error) { if len(command) == 0 { return nil, errors.New("Empty shell command") } split, err := shlex.Split(command) if err != nil { return nil, err } cmd := exec.Command(split[0], split[1:]...) stdout, err := cmd.StdoutPipe() if err != nil { return nil, err } stderr, err := cmd.StderrPipe() if err != nil { return nil, err }
func serviceAdd(args Add) { if args.ContainerEnvironment == nil { args.ContainerEnvironment = make([]string, 0) } // Parse command if cmdAddCommand != "" { command, err := shlex.Split(cmdAddCommand) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerCommand = command } // Parse Entrypoint if cmdAddEntrypoint != "" { entrypoint, err := shlex.Split(cmdAddEntrypoint) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerEntrypoint = entrypoint } // Parse volumes if len(cmdAddVolume) > 0 { args.Volumes = make(map[string]VolumeConfig) } for _, vol := range cmdAddVolume { t := strings.Split(vol, ":") if len(t) == 2 { args.Volumes[t[0]] = VolumeConfig{Size: t[1]} } else if len(t) == 1 { args.Volumes[t[0]] = VolumeConfig{Size: "10"} } else { fmt.Fprintf(os.Stderr, "Error: Volume parameter '%s' not formated correctly\n", vol) os.Exit(1) } } // Parse links if len(redeployLink) > 0 { args.Links = make(map[string]string) } for _, link := range cmdAddLink { t := strings.Split(link, ":") if len(t) == 1 { args.Links[t[0]] = t[0] } else { args.Links[t[0]] = t[1] } } // Parse ContainerNetworks arguments for _, network := range cmdAddNetwork { args.ContainerNetwork[network] = make(map[string][]string) } for _, gat := range cmdAddGateway { t := strings.Split(gat, ":") if len(t) != 2 { fmt.Fprintf(os.Stderr, "Invalid gateway parameter, should be \"input:output\". Typically, output will be one of 'predictor', 'public'") os.Exit(1) } if _, ok := args.ContainerNetwork[t[0]]; !ok { fmt.Fprintf(os.Stderr, "Automatically adding %s to network list\n", t[0]) args.ContainerNetwork[t[0]] = make(map[string][]string) } if _, ok := args.ContainerNetwork[t[1]]; !ok { fmt.Fprintf(os.Stderr, "Automatically adding %s to network list\n", t[0]) args.ContainerNetwork[t[1]] = make(map[string][]string) } args.ContainerNetwork[t[0]]["gateway_to"] = append(args.ContainerNetwork[t[0]]["gateway_to"], t[1]) } // Parse ContainerPorts args.ContainerPorts = parsePublishedPort(addPublish) path := fmt.Sprintf("/applications/%s/services/%s", args.Application, args.Service) body, err := json.MarshalIndent(args, " ", " ") if err != nil { fmt.Fprintf(os.Stderr, "Fatal: %s\n", err) return } stream := "" if !addBatch { stream = "?stream" } buffer, code, err := internal.Stream("POST", path+stream, body) // http.Request failed for some reason if err != nil { fmt.Fprintf(os.Stderr, "Error: %s\n", err) return } // If we are in ensure mode, fallback to redeploy if code == 409 && cmdAddRedeploy { ensureMode(args) return } else if code >= 400 { body, err = ioutil.ReadAll(buffer) internal.Check(err) internal.FormatOutputError(body) return } line, err := internal.DisplayStream(buffer) // If we are in ensure mode, fallback to redeploy if err != nil { e := internal.DecodeError(line) if e != nil && e.Code == 409 && cmdAddRedeploy { ensureMode(args) return } internal.FormatOutputError(line) return } // Always start service if internal.Format == "pretty" { fmt.Fprintf(os.Stderr, "Starting service %s/%s...\n", args.Application, args.Service) } serviceStart(args.Application, args.Service, addBatch) }
func main() { flag.Parse() if *server == "" { fmt.Fprintf(os.Stderr, "--server cannot be empty.\n") os.Exit(1) } if *port != 0 { http.Handle("/metrics", prometheus.Handler()) go http.ListenAndServe(fmt.Sprintf(":%v", *port), nil) } var opts []grpc.DialOption if len(*caFile) != 0 { var creds credentials.TransportAuthenticator var err error creds, err = credentials.NewClientTLSFromFile(*caFile, "") if err != nil { log.Exitf("Failed to create TLS credentials %v\n", err) } opts = append(opts, grpc.WithTransportCredentials(creds)) } else { opts = append(opts, grpc.WithInsecure()) } c := &Multiclient{ addr: *server, opts: []doorman.Option{doorman.DialOpts(opts...)}, clients: make(map[string]*doorman.Client), resources: make(map[key]doorman.Resource), capacities: make(map[key]float64), } defer c.Close() line, err := readline.NewEx(&readline.Config{ Prompt: "> ", HistoryFile: "/tmp/doorman_shell.tmp", InterruptPrompt: "\nInterrupt, Press Ctrl+D to exit", }) if err != nil { fmt.Printf("ERROR: %v\n", err) os.Exit(1) } for { data, err := line.Readline() if err == io.EOF { break } if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) } command, err := shlex.Split(data) if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) } err = c.Eval(command) if err == io.EOF { break } if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) } } }
func serviceRedeploy(args Redeploy) { // Parse volumes if len(redeployVolume) > 0 { args.Volumes = make(map[string]VolumeConfig) } // Parse command if redeployCommand != "" { command, err := shlex.Split(redeployCommand) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerCommand = command } // Parse Entrypoint if redeployEntrypoint != "" { entrypoint, err := shlex.Split(redeployEntrypoint) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerEntrypoint = entrypoint } for _, vol := range redeployVolume { t := strings.Split(vol, ":") if len(t) == 2 { args.Volumes[t[0]] = VolumeConfig{Size: t[1]} } else if len(t) == 1 { args.Volumes[t[0]] = VolumeConfig{Size: "10"} } else { fmt.Fprintf(os.Stderr, "Error: Volume parameter '%s' not formated correctly\n", vol) os.Exit(1) } } // Parse links if len(redeployLink) > 0 { args.Links = make(map[string]string) } for _, link := range redeployLink { t := strings.Split(link, ":") if len(t) == 1 { args.Links[t[0]] = t[0] } else { args.Links[t[0]] = t[1] } } // Parse ContainerNetworks arguments if len(redeployNetwork) > 0 { args.ContainerNetwork = make(map[string]map[string][]string) } for _, network := range redeployNetwork { args.ContainerNetwork[network] = make(map[string][]string) } // Load Pool args.Pool = redeployPool // Parse ContainerPorts args.ContainerPorts = parsePublishedPort(redeployPublished) app := args.Application service := args.Service // Parse NetworkAllow args.ContainerPorts = parseWhitelistedCidrs(redeployNetworkAllow, args.ContainerPorts) // Actual redeploy doServiceRedeploy(args, app, service) }
// InitEnv parses our data into our config func (s *DockerPushStep) InitEnv(env *util.Environment) { if username, ok := s.data["username"]; ok { s.username = env.Interpolate(username) } if password, ok := s.data["password"]; ok { s.password = env.Interpolate(password) } if email, ok := s.data["email"]; ok { s.email = env.Interpolate(email) } if authServer, ok := s.data["auth-server"]; ok { s.authServer = env.Interpolate(authServer) } if repository, ok := s.data["repository"]; ok { s.repository = env.Interpolate(repository) } if tags, ok := s.data["tag"]; ok { splitTags := util.SplitSpaceOrComma(tags) interpolatedTags := make([]string, len(splitTags)) for i, tag := range splitTags { interpolatedTags[i] = env.Interpolate(tag) } s.tags = interpolatedTags } if author, ok := s.data["author"]; ok { s.author = env.Interpolate(author) } if message, ok := s.data["message"]; ok { s.message = env.Interpolate(message) } if ports, ok := s.data["ports"]; ok { iPorts := env.Interpolate(ports) parts := util.SplitSpaceOrComma(iPorts) portmap := make(map[docker.Port]struct{}) for _, port := range parts { port = strings.TrimSpace(port) if !strings.Contains(port, "/") { port = port + "/tcp" } portmap[docker.Port(port)] = struct{}{} } s.ports = portmap } if volumes, ok := s.data["volumes"]; ok { iVolumes := env.Interpolate(volumes) parts := util.SplitSpaceOrComma(iVolumes) volumemap := make(map[string]struct{}) for _, volume := range parts { volume = strings.TrimSpace(volume) volumemap[volume] = struct{}{} } s.volumes = volumemap } if workingDir, ok := s.data["working-dir"]; ok { s.workingDir = env.Interpolate(workingDir) } if registry, ok := s.data["registry"]; ok { // s.registry = env.Interpolate(registry) s.registry = normalizeRegistry(env.Interpolate(registry)) } else { // s.registry = "https://registry.hub.docker.com" s.registry = normalizeRegistry("https://registry.hub.docker.com") } if cmd, ok := s.data["cmd"]; ok { parts, err := shlex.Split(cmd) if err == nil { s.cmd = parts } } if entrypoint, ok := s.data["entrypoint"]; ok { parts, err := shlex.Split(entrypoint) if err == nil { s.entrypoint = parts } } if envi, ok := s.data["env"]; ok { parsedEnv, err := shlex.Split(envi) if err == nil { interpolatedEnv := make([]string, len(parsedEnv)) for i, envVar := range parsedEnv { interpolatedEnv[i] = env.Interpolate(envVar) } s.env = interpolatedEnv } } if stopsignal, ok := s.data["stopsignal"]; ok { s.stopSignal = env.Interpolate(stopsignal) } if labels, ok := s.data["labels"]; ok { parsedLabels, err := shlex.Split(labels) if err == nil { labelMap := make(map[string]string) for _, labelPair := range parsedLabels { pair := strings.Split(labelPair, "=") labelMap[env.Interpolate(pair[0])] = env.Interpolate(pair[1]) } s.labels = labelMap } } if user, ok := s.data["user"]; ok { s.user = env.Interpolate(user) } if forceTags, ok := s.data["force-tags"]; ok { ft, err := strconv.ParseBool(forceTags) if err == nil { s.forceTags = ft } } else { s.forceTags = true } }
// Run creates the container and runs it. func (b *DockerBox) Run(ctx context.Context, env *util.Environment) (*docker.Container, error) { err := b.RunServices(ctx, env) if err != nil { return nil, err } b.logger.Debugln("Starting base box:", b.Name) // TODO(termie): maybe move the container manipulation outside of here? client := b.client // Import the environment myEnv := dockerEnv(b.config.Env, env) var entrypoint []string if b.entrypoint != "" { entrypoint, err = shlex.Split(b.entrypoint) if err != nil { return nil, err } } cmd, err := shlex.Split(b.cmd) if err != nil { return nil, err } var ports map[docker.Port]struct{} if len(b.options.PublishPorts) > 0 { ports = exposedPorts(b.options.PublishPorts) } else if b.options.ExposePorts { ports = exposedPorts(b.config.Ports) } binds, err := b.binds(env) portsToBind := []string{""} if len(b.options.PublishPorts) >= 1 { b.logger.Warnln("--publish is deprecated, please use --expose-ports and define the ports for the boxes. See: https://github.com/wercker/wercker/pull/161") portsToBind = b.options.PublishPorts } else if b.options.ExposePorts { portsToBind = b.config.Ports } hostConfig := &docker.HostConfig{ Binds: binds, Links: b.links(), PortBindings: portBindings(portsToBind), DNS: b.dockerOptions.DockerDNS, } // Make and start the container container, err := client.CreateContainer( docker.CreateContainerOptions{ Name: b.getContainerName(), Config: &docker.Config{ Image: env.Interpolate(b.Name), Tty: false, OpenStdin: true, Cmd: cmd, Env: myEnv, AttachStdin: true, AttachStdout: true, AttachStderr: true, ExposedPorts: ports, NetworkDisabled: b.networkDisabled, DNS: b.dockerOptions.DockerDNS, Entrypoint: entrypoint, // Volumes: volumes, }, HostConfig: hostConfig, }) if err != nil { return nil, err } b.logger.Debugln("Docker Container:", container.ID) if err != nil { return nil, err } client.StartContainer(container.ID, hostConfig) b.container = container return container, nil }
func resourceLXCContainerCreate(d *schema.ResourceData, meta interface{}) error { var c *lxc.Container config := meta.(*Config) backendType, err := lxcCheckBackend(d.Get("backend").(string)) if err != nil { return err } name := d.Get("name").(string) c, err = lxc.NewContainer(name, config.LXCPath) if err != nil { return err } log.Printf("[INFO] Attempting to create container %s\n", c.Name()) var ea []string for _, v := range d.Get("template_extra_args").([]interface{}) { ea = append(ea, v.(string)) } var options lxc.TemplateOptions templateName := d.Get("template_name").(string) if templateName == "download" { options = lxc.TemplateOptions{ Backend: backendType, Template: d.Get("template_name").(string), Distro: d.Get("template_distro").(string), Release: d.Get("template_release").(string), Arch: d.Get("template_arch").(string), Variant: d.Get("template_variant").(string), Server: d.Get("template_server").(string), KeyID: d.Get("template_key_id").(string), KeyServer: d.Get("template_key_server").(string), FlushCache: d.Get("template_flush_cache").(bool), ForceCache: d.Get("template_force_cache").(bool), DisableGPGValidation: d.Get("template_disable_gpg_validation").(bool), ExtraArgs: ea, } } else { options = lxc.TemplateOptions{ Backend: backendType, Template: d.Get("template_name").(string), Release: d.Get("template_release").(string), Arch: d.Get("template_arch").(string), FlushCache: d.Get("template_flush_cache").(bool), ExtraArgs: ea, } } if err := c.Create(options); err != nil { return err } d.SetId(c.Name()) if err := lxcOptions(c, d, config); err != nil { return err } // causes lxc to re-read the config file c, err = lxc.NewContainer(name, config.LXCPath) if err != nil { return err } log.Printf("[INFO] Starting container %s\n", c.Name()) if err := c.Start(); err != nil { return fmt.Errorf("Unable to start container: %s", err) } if err := lxcWaitForState(c, config.LXCPath, []string{"STOPPED", "STARTING"}, "RUNNING"); err != nil { return err } if commands, defined := d.GetOk("exec"); defined { if defined { for _, command := range commands.([]interface{}) { args, err := shlex.Split(command.(string)) if err != nil { log.Printf("[ERROR] Error parsing arguments for command %d, skipping to next command", command.(string)) } else { log.Printf("[INFO] Running command in container %s : %s\n", c.Name(), command.(string)) c.RunCommand(args, lxc.DefaultAttachOptions) } } } } log.Printf("[INFO] Waiting container to startup networking...\n") c.WaitIPAddresses(5 * time.Second) return resourceLXCContainerRead(d, meta) }
// InitEnv parses our data into our config func (s *DockerPushStep) InitEnv(env *util.Environment) { if email, ok := s.data["email"]; ok { s.email = env.Interpolate(email) } if authServer, ok := s.data["auth-server"]; ok { s.authServer = env.Interpolate(authServer) } if repository, ok := s.data["repository"]; ok { s.repository = env.Interpolate(repository) } if tags, ok := s.data["tag"]; ok { splitTags := util.SplitSpaceOrComma(tags) interpolatedTags := make([]string, len(splitTags)) for i, tag := range splitTags { interpolatedTags[i] = env.Interpolate(tag) } s.tags = interpolatedTags } if author, ok := s.data["author"]; ok { s.author = env.Interpolate(author) } if message, ok := s.data["message"]; ok { s.message = env.Interpolate(message) } if ports, ok := s.data["ports"]; ok { iPorts := env.Interpolate(ports) parts := util.SplitSpaceOrComma(iPorts) portmap := make(map[docker.Port]struct{}) for _, port := range parts { port = strings.TrimSpace(port) if !strings.Contains(port, "/") { port = port + "/tcp" } portmap[docker.Port(port)] = struct{}{} } s.ports = portmap } if volumes, ok := s.data["volumes"]; ok { iVolumes := env.Interpolate(volumes) parts := util.SplitSpaceOrComma(iVolumes) volumemap := make(map[string]struct{}) for _, volume := range parts { volume = strings.TrimSpace(volume) volumemap[volume] = struct{}{} } s.volumes = volumemap } if workingDir, ok := s.data["working-dir"]; ok { s.workingDir = env.Interpolate(workingDir) } if cmd, ok := s.data["cmd"]; ok { parts, err := shlex.Split(cmd) if err == nil { s.cmd = parts } } if entrypoint, ok := s.data["entrypoint"]; ok { parts, err := shlex.Split(entrypoint) if err == nil { s.entrypoint = parts } } if envi, ok := s.data["env"]; ok { parsedEnv, err := shlex.Split(envi) if err == nil { interpolatedEnv := make([]string, len(parsedEnv)) for i, envVar := range parsedEnv { interpolatedEnv[i] = env.Interpolate(envVar) } s.env = interpolatedEnv } } if stopsignal, ok := s.data["stopsignal"]; ok { s.stopSignal = env.Interpolate(stopsignal) } if labels, ok := s.data["labels"]; ok { parsedLabels, err := shlex.Split(labels) if err == nil { labelMap := make(map[string]string) for _, labelPair := range parsedLabels { pair := strings.Split(labelPair, "=") labelMap[env.Interpolate(pair[0])] = env.Interpolate(pair[1]) } s.labels = labelMap } } if user, ok := s.data["user"]; ok { s.user = env.Interpolate(user) } if forceTags, ok := s.data["force-tags"]; ok { ft, err := strconv.ParseBool(forceTags) if err == nil { s.forceTags = ft } } else { s.forceTags = true } //build auther opts := dockerauth.CheckAccessOptions{} if username, ok := s.data["username"]; ok { opts.Username = env.Interpolate(username) } if password, ok := s.data["password"]; ok { opts.Password = env.Interpolate(password) } if awsAccessKey, ok := s.data["aws-access-key"]; ok { opts.AwsAccessKey = env.Interpolate(awsAccessKey) } if awsSecretKey, ok := s.data["aws-secret-key"]; ok { opts.AwsSecretKey = env.Interpolate(awsSecretKey) } if awsRegion, ok := s.data["aws-region"]; ok { opts.AwsRegion = env.Interpolate(awsRegion) } if awsAuth, ok := s.data["aws-strict-auth"]; ok { auth, err := strconv.ParseBool(awsAuth) if err == nil { opts.AwsStrictAuth = auth } } if awsRegistryID, ok := s.data["aws-registry-id"]; ok { opts.AwsRegistryID = env.Interpolate(awsRegistryID) } if registry, ok := s.data["registry"]; ok { opts.Registry = dockerauth.NormalizeRegistry(env.Interpolate(registry)) } auther, _ := dockerauth.GetRegistryAuthenticator(opts) s.authenticator = auther }
// Run executes the service func (b *InternalServiceBox) Run(ctx context.Context, env *util.Environment, links []string) (*docker.Container, error) { e, err := core.EmitterFromContext(ctx) if err != nil { return nil, err } f := &util.Formatter{} client, err := NewDockerClient(b.dockerOptions) if err != nil { return nil, err } // Import the environment and command myEnv := dockerEnv(b.config.Env, env) origEntrypoint := b.image.Config.Entrypoint origCmd := b.image.Config.Cmd cmdInfo := []string{} var entrypoint []string if b.entrypoint != "" { entrypoint, err = shlex.Split(b.entrypoint) if err != nil { return nil, err } cmdInfo = append(cmdInfo, entrypoint...) } else { cmdInfo = append(cmdInfo, origEntrypoint...) } var cmd []string if b.config.Cmd != "" { cmd, err = shlex.Split(b.config.Cmd) if err != nil { return nil, err } cmdInfo = append(cmdInfo, cmd...) } else { cmdInfo = append(cmdInfo, origCmd...) } container, err := client.CreateContainer( docker.CreateContainerOptions{ Name: b.getContainerName(), Config: &docker.Config{ Image: b.Name, Cmd: cmd, Env: myEnv, NetworkDisabled: b.networkDisabled, DNS: b.dockerOptions.DockerDNS, Entrypoint: entrypoint, }, }) if err != nil { return nil, err } out := []string{} for _, part := range cmdInfo { if strings.Contains(part, " ") { out = append(out, fmt.Sprintf("%q", part)) } else { out = append(out, part) } } if b.options.Verbose { b.logger.Println(f.Info(fmt.Sprintf("Starting service %s", b.ShortName), strings.Join(out, " "))) } client.StartContainer(container.ID, &docker.HostConfig{ DNS: b.dockerOptions.DockerDNS, Links: links, }) b.container = container go func() { status, err := client.WaitContainer(container.ID) if err != nil { b.logger.Errorln("Error waiting", err) } b.logger.Debugln("Service container finished with status code:", status, container.ID) if status != 0 { var errstream bytes.Buffer var outstream bytes.Buffer // recv := make(chan string) // outputStream := NewReceiver(recv) opts := docker.LogsOptions{ Container: container.ID, Stdout: true, Stderr: true, ErrorStream: &errstream, OutputStream: &outstream, RawTerminal: false, } err = client.Logs(opts) if err != nil { b.logger.Panicln(err) } e.Emit(core.Logs, &core.LogsArgs{ Stream: fmt.Sprintf("%s-stdout", b.Name), Logs: outstream.String(), }) e.Emit(core.Logs, &core.LogsArgs{ Stream: fmt.Sprintf("%s-stderr", b.Name), Logs: errstream.String(), }) } }() return container, nil }
// Run creates the container and runs it. func (b *DockerBox) Run(ctx context.Context, env *util.Environment) (*docker.Container, error) { err := b.RunServices(ctx, env) if err != nil { return nil, err } b.logger.Debugln("Starting base box:", b.Name) // TODO(termie): maybe move the container manipulation outside of here? client := b.client // Import the environment myEnv := dockerEnv(b.config.Env, env) var entrypoint []string if b.entrypoint != "" { entrypoint, err = shlex.Split(b.entrypoint) if err != nil { return nil, err } } cmd, err := shlex.Split(b.cmd) if err != nil { return nil, err } // Make and start the container container, err := client.CreateContainer( docker.CreateContainerOptions{ Name: b.getContainerName(), Config: &docker.Config{ Image: env.Interpolate(b.Name), Tty: false, OpenStdin: true, Cmd: cmd, Env: myEnv, AttachStdin: true, AttachStdout: true, AttachStderr: true, ExposedPorts: exposedPorts(b.options.PublishPorts), NetworkDisabled: b.networkDisabled, DNS: b.dockerOptions.DockerDNS, Entrypoint: entrypoint, // Volumes: volumes, }, }) if err != nil { return nil, err } b.logger.Debugln("Docker Container:", container.ID) binds, err := b.binds(env) if err != nil { return nil, err } client.StartContainer(container.ID, &docker.HostConfig{ Binds: binds, Links: b.links(), PortBindings: portBindings(b.options.PublishPorts), DNS: b.dockerOptions.DockerDNS, }) b.container = container return container, nil }