Exemple #1
0
// Ensure there is a docker binary in the path,
// and printing an error if its version is below the minimal requirement.
func checkDockerClient() {
	output, err := commandOutput("docker", []string{"--version"})
	if err != nil {
		panic(StatusError{errors.New("Error when probing Docker's client version. Is docker installed and within the $PATH?"), 69})
	}
	re := regexp.MustCompile("([0-9]+)\\.([0-9]+)\\.?([0-9]+)?")
	rawVersions := re.FindStringSubmatch(string(output))
	var versions []int
	for _, rawVersion := range rawVersions[1:] {
		version, err := strconv.Atoi(rawVersion)
		if err != nil {
			print.Errorf("Error when parsing Docker's version %v: %v", rawVersion, err)
			break
		}
		versions = append(versions, version)
	}

	for i, expectedVersion := range requiredDockerVersion {
		if versions[i] > expectedVersion {
			break
		}
		if versions[i] < expectedVersion {
			print.Errorf("Unsupported client version! Please upgrade to Docker %v or later.\n", intJoin(requiredDockerVersion, "."))
		}
	}
}
Exemple #2
0
// Remove container
func (c *container) Rm(force bool) {
	if c.Exists() {
		containerIsRunning := c.Running()
		if !force && containerIsRunning {
			print.Errorf("Container %s is running and cannot be removed. Use --force to remove anyway.\n", c.Name())
		} else {
			args := []string{"rm"}
			if force && containerIsRunning {
				executeHook(c.Hooks().PreStop())
				args = append(args, "--force")
			}
			if c.RmParams.Volumes {
				fmt.Printf("Removing container %s and its volumes ... ", c.Name())
				args = append(args, "--volumes")
			} else {
				fmt.Printf("Removing container %s ... ", c.Name())
			}
			args = append(args, c.Name())
			executeCommand("docker", args)
			if force && containerIsRunning {
				executeHook(c.Hooks().PostStop())
			}
			c.id = ""
		}
	}
}
Exemple #3
0
// dumps the dependency graph as a DOT to the writer
func (graph DependencyGraph) DOT(writer io.Writer, targetedContainers Containers) {
	const dotTemplate = `{{ $targetedContainers := .TargetedContainers }}digraph {
{{ range $name, $dependencies := .Graph }}{{ with $dependencies }}  "{{ $name }}" [style=bold{{ range $targetedContainers }}{{ if eq $name .Name }},color=red{{ end }}{{ end }}]
{{ range .Link }}  "{{ $name }}"->"{{ . }}"
{{ end }}{{ range .VolumesFrom }}  "{{ $name }}"->"{{ . }}" [style=dashed]
{{ end }}{{ if ne .Net "" }}  "{{ $name }}"->"{{ .Net }}" [style=dotted]
{{ end }}{{ end }}{{ end }}}
`
	template, err := template.New("dot").Parse(dotTemplate)
	if err != nil {
		print.Errorf("ERROR: %s\n", err)
		return
	}
	err = template.Execute(writer, dotInput{graph, targetedContainers})
	if err != nil {
		print.Errorf("ERROR: %s\n", err)
	}
}
Exemple #4
0
// Start container
func (container Container) start() {
	if container.exists() {
		if !container.running() {
			fmt.Printf("Starting container %s ... ", container.Name())
			args := []string{"start", container.Name()}
			executeCommand("docker", args)
		}
	} else {
		print.Errorf("Container %s does not exist.\n", container.Name())
	}
}
Exemple #5
0
// Stats about containers.
func (containers Containers) stats() {
	args := []string{"stats"}
	for _, container := range containers {
		if container.Running() {
			args = append(args, container.Name())
		}
	}
	if len(args) > 1 {
		executeCommand("docker", args)
	} else {
		print.Errorf("None of the targeted container is running.\n")
	}
}
Exemple #6
0
// returns a function to be set as a cobra command run, wrapping a command meant to be run according to the config
func configCommand(wrapped func(config Config), forceOrder bool) func(cmd *cobra.Command, args []string) {
	return func(cmd *cobra.Command, args []string) {
		for _, value := range []string{options.cascadeDependencies, options.cascadeAffected, options.ignoreMissing} {
			if value != "none" && value != "all" && value != "link" && value != "volumesFrom" && value != "net" {
				print.Errorf("Error: invalid dependency type value: %v", value)
				cmd.Usage()
				panic(StatusError{status: 64})
			}
		}

		// Set target from args
		options.target = args
		cfg = NewConfig(options, forceOrder)
		if containers := cfg.TargetedContainers(); len(containers) == 0 {
			print.Errorf("ERROR: Command cannot be applied to any container.")
		} else {
			if isVerbose() {
				print.Infof("Command will be applied to: %v\n\n", strings.Join(containers.names(), ", "))
			}
			wrapped(cfg)
		}
	}
}
Exemple #7
0
func (r *RunParameters) Cmd() []string {
	var cmd []string
	if r.RawCmd != nil {
		switch rawCmd := r.RawCmd.(type) {
		case string:
			if len(rawCmd) > 0 {
				cmds, err := shlex.Split(os.ExpandEnv(rawCmd))
				if err != nil {
					print.Errorf("Error when parsing cmd `%v`: %v. Proceeding with %q.", rawCmd, err, cmds)
				}
				cmd = append(cmd, cmds...)
			}
		case []interface{}:
			cmds := make([]string, len(rawCmd))
			for i, v := range rawCmd {
				cmds[i] = os.ExpandEnv(v.(string))
			}
			cmd = append(cmd, cmds...)
		default:
			print.Errorf("cmd is of unknown type!")
		}
	}
	return cmd
}
Exemple #8
0
// Remove container
func (container Container) rm() {
	if container.exists() {
		if container.running() {
			print.Errorf("Container %s is running and cannot be removed.\n", container.Name())
		} else {
			args := []string{"rm"}
			if container.Rm.Volumes {
				fmt.Printf("Removing container %s and its volumes ... ", container.Name())
				args = append(args, "--volumes")
			} else {
				fmt.Printf("Removing container %s ... ", container.Name())
			}
			args = append(args, container.Name())
			executeCommand("docker", args)
		}
	}
}
Exemple #9
0
// Start container
func (c *container) Start() {
	if c.Exists() {
		if !c.Running() {
			fmt.Printf("Starting container %s ... ", c.Name())
			args := []string{"start"}
			if c.StartParams.Attach {
				args = append(args, "--attach")
			}
			if c.StartParams.Interactive {
				args = append(args, "--interactive")
			}
			args = append(args, c.Name())
			executeCommand("docker", args)
		}
	} else {
		print.Errorf("Container %s does not exist.\n", c.Name())
	}
}
Exemple #10
0
func (r *RunParameters) Label() []string {
	var label []string
	if r.RawLabel != nil {
		switch rawLabel := r.RawLabel.(type) {
		case []interface{}:
			for _, v := range rawLabel {
				label = append(label, os.ExpandEnv(v.(string)))
			}
		case map[interface{}]interface{}:
			for k, v := range rawLabel {
				label = append(label, os.ExpandEnv(k.(string))+"="+os.ExpandEnv(v.(string)))
			}
		default:
			print.Errorf("label is of unknown type!")
		}
	}
	return label
}
Exemple #11
0
func (r *RunParameters) Env() []string {
	var env []string
	if r.RawEnv != nil {
		switch rawEnv := r.RawEnv.(type) {
		case []interface{}:
			for _, v := range rawEnv {
				env = append(env, os.ExpandEnv(v.(string)))
			}
		case map[interface{}]interface{}:
			for k, v := range rawEnv {
				env = append(env, os.ExpandEnv(k.(string))+"="+os.ExpandEnv(v.(string)))
			}
		default:
			print.Errorf("env is of unknown type!")
		}
	}
	return env
}
Exemple #12
0
func (r *RunParameters) Cmd() []string {
	var cmd []string
	if r.RawCmd != nil {
		switch rawCmd := r.RawCmd.(type) {
		case string:
			if len(rawCmd) > 0 {
				cmd = append(cmd, os.ExpandEnv(rawCmd))
			}
		case []interface{}:
			cmds := make([]string, len(rawCmd))
			for i, v := range rawCmd {
				cmds[i] = os.ExpandEnv(v.(string))
			}
			cmd = append(cmd, cmds...)
		default:
			print.Errorf("cmd is of unknown type!")
		}
	}
	return cmd
}
Exemple #13
0
func RealMain() {
	// On panic, recover the error, display it and return the given status code if any
	defer func() {
		var statusError StatusError

		switch err := recover().(type) {
		case StatusError:
			statusError = err
		case error:
			statusError = StatusError{err, 1}
		case string:
			statusError = StatusError{errors.New(err), 1}
		default:
			statusError = StatusError{}
		}

		if statusError.error != nil {
			print.Errorf("ERROR: %s\n", statusError.error)
		}
		os.Exit(statusError.status)
	}()

	handleCmd()
}