func ParseCommand(command string) ([]string, error) {
	args, err := shlex.Split(command)
	if err != nil {
		return []string{}, err
	}
	return args, err
}
Exemple #2
0
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
}
Exemple #3
0
// 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
}
Exemple #4
0
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
}
Exemple #5
0
// 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
}
Exemple #6
0
// 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
}
Exemple #7
0
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")
}
Exemple #8
0
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())
		}
	}
}
Exemple #9
0
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()
	}
}
Exemple #10
0
	"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
		}
Exemple #11
0
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)
}
Exemple #12
0
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)
		}
	}
}
Exemple #13
0
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)
}
Exemple #14
0
// 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
	}
}
Exemple #15
0
// 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)
}
Exemple #17
0
// 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
}
Exemple #18
0
// 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
}
Exemple #19
0
// 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
}