Beispiel #1
0
func (c *container) UpdateResources(r *Resource) error {
	sr := ocs.Resources{
		Memory: &ocs.Memory{
			Limit:       u64Ptr(uint64(r.Memory)),
			Reservation: u64Ptr(uint64(r.MemoryReservation)),
			Swap:        u64Ptr(uint64(r.MemorySwap)),
			Kernel:      u64Ptr(uint64(r.KernelMemory)),
		},
		CPU: &ocs.CPU{
			Shares: u64Ptr(uint64(r.CPUShares)),
			Quota:  u64Ptr(uint64(r.CPUQuota)),
			Period: u64Ptr(uint64(r.CPUPeriod)),
			Cpus:   &r.CpusetCpus,
			Mems:   &r.CpusetMems,
		},
		BlockIO: &ocs.BlockIO{
			Weight: &r.BlkioWeight,
		},
	}

	srStr := bytes.NewBuffer(nil)
	if err := json.NewEncoder(srStr).Encode(&sr); err != nil {
		return err
	}

	args := c.runtimeArgs
	args = append(args, "update", "-r", "-", c.id)
	cmd := exec.Command(c.runtime, args...)
	cmd.Stdin = srStr
	b, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf(string(b))
	}
	return nil
}
Beispiel #2
0
func (c *container) Resume() error {
	args := c.runtimeArgs
	args = append(args, "resume", c.id)
	b, err := exec.Command(c.runtime, args...).CombinedOutput()
	if err != nil {
		return fmt.Errorf("%s: %q", err.Error(), string(b))
	}
	return nil
}
Beispiel #3
0
func (d *directProcess) delete() {
	if d.console != nil {
		d.console.Close()
	}
	d.io.Close()
	d.Wait()
	if !d.exec {
		exec.Command(d.container.runtime, append(d.container.runtimeArgs, "delete", d.container.id)...).Run()
	}
}
Beispiel #4
0
func (c *container) Delete() error {
	err := os.RemoveAll(filepath.Join(c.root, c.id))

	args := c.runtimeArgs
	args = append(args, "delete", c.id)
	if derr := exec.Command(c.runtime, args...).Run(); err == nil {
		err = derr
	}
	return err
}
Beispiel #5
0
// cmd runs `apparmor_parser` with the passed arguments.
func cmd(dir string, arg ...string) (string, error) {
	c := exec.Command(binary, arg...)
	c.Dir = dir

	output, err := c.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), string(output), err)
	}

	return string(output), nil
}
Beispiel #6
0
func (p *process) Start() error {
	cmd := exec.Command(p.container.shim,
		p.container.id, p.container.bundle, p.container.runtime,
	)
	cmd.Dir = p.root
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Setpgid: true,
	}

	return p.startCmd(cmd)
}
Beispiel #7
0
func (c *container) Pids() ([]int, error) {
	args := c.runtimeArgs
	args = append(args, "ps", "--format=json", c.id)
	out, err := exec.Command(c.runtime, args...).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s: %q", err.Error(), out)
	}
	var pids []int
	if err := json.Unmarshal(out, &pids); err != nil {
		return nil, err
	}
	return pids, nil
}
Beispiel #8
0
func (c *container) Checkpoint(cpt Checkpoint, checkpointDir string) error {
	if checkpointDir == "" {
		checkpointDir = filepath.Join(c.bundle, "checkpoints")
	}

	if err := os.MkdirAll(checkpointDir, 0755); err != nil {
		return err
	}

	path := filepath.Join(checkpointDir, cpt.Name)
	if err := os.Mkdir(path, 0755); err != nil {
		return err
	}
	f, err := os.Create(filepath.Join(path, "config.json"))
	if err != nil {
		return err
	}
	cpt.Created = time.Now()
	err = json.NewEncoder(f).Encode(cpt)
	f.Close()
	if err != nil {
		return err
	}
	args := []string{
		"checkpoint",
		"--image-path", path,
	}
	add := func(flags ...string) {
		args = append(args, flags...)
	}
	add(c.runtimeArgs...)
	if !cpt.Exit {
		add("--leave-running")
	}
	if cpt.Shell {
		add("--shell-job")
	}
	if cpt.Tcp {
		add("--tcp-established")
	}
	if cpt.UnixSockets {
		add("--ext-unix-sk")
	}
	add(c.id)
	out, err := exec.Command(c.runtime, args...).CombinedOutput()
	if err != nil {
		return fmt.Errorf("%s: %q", err.Error(), string(out))
	}
	return err
}
Beispiel #9
0
func (c *container) Stats() (*Stat, error) {
	now := time.Now()
	args := c.runtimeArgs
	args = append(args, "events", "--stats", c.id)
	out, err := exec.Command(c.runtime, args...).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s: %q", err.Error(), out)
	}
	s := struct {
		Data *Stat `json:"data"`
	}{}
	if err := json.Unmarshal(out, &s); err != nil {
		return nil, err
	}
	s.Data.Timestamp = now
	return s.Data, nil
}
Beispiel #10
0
// Status implements the runtime Container interface.
func (c *container) Status() (State, error) {
	args := c.runtimeArgs
	args = append(args, "state", c.id)

	out, err := exec.Command(c.runtime, args...).CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("%s: %q", err.Error(), out)
	}

	// We only require the runtime json output to have a top level Status field.
	var s struct {
		Status State `json:"status"`
	}
	if err := json.Unmarshal(out, &s); err != nil {
		return "", err
	}
	return s.Status, nil
}
Beispiel #11
0
func xzDecompress(archive io.Reader) (io.ReadCloser, <-chan struct{}, error) {
	args := []string{"xz", "-d", "-c", "-q"}

	return cmdStream(exec.Command(args[0], args[1:]...), archive)
}
Beispiel #12
0
func git(args ...string) ([]byte, error) {
	return exec.Command("git", args...).CombinedOutput()
}
Beispiel #13
0
func (d *directProcess) Start() error {
	cwd, err := filepath.Abs(d.root)
	if err != nil {
		return err
	}

	stdin, stdout, stderr, err := d.openIO()
	if err != nil {
		return nil
	}

	checkpoint, err := d.loadCheckpoint(d.container.bundle)
	if err != nil {
		return err
	}

	logPath := filepath.Join(cwd, "log.json")
	args := append([]string{
		"--log", logPath,
		"--log-format", "json",
	}, d.container.runtimeArgs...)
	if d.exec {
		args = append(args, "exec",
			"--process", filepath.Join(cwd, "process.json"),
			"--console", d.consolePath,
		)
	} else if checkpoint != nil {
		args = append(args, "restore",
			"--image-path", filepath.Join(d.container.bundle, "checkpoints", checkpoint.Name),
		)
		add := func(flags ...string) {
			args = append(args, flags...)
		}
		if checkpoint.Shell {
			add("--shell-job")
		}
		if checkpoint.Tcp {
			add("--tcp-established")
		}
		if checkpoint.UnixSockets {
			add("--ext-unix-sk")
		}
		if d.container.noPivotRoot {
			add("--no-pivot")
		}
	} else {
		args = append(args, "start",
			"--bundle", d.container.bundle,
			"--console", d.consolePath,
		)
		if d.container.noPivotRoot {
			args = append(args, "--no-pivot")
		}
	}
	args = append(args,
		"-d",
		"--pid-file", filepath.Join(cwd, "pid"),
		d.container.id,
	)
	cmd := exec.Command(d.container.runtime, args...)
	cmd.Dir = d.container.bundle
	cmd.Stdin = stdin
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	// set the parent death signal to SIGKILL so that if containerd dies the container
	// process also dies
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Pdeathsig: syscall.SIGKILL,
	}

	exitSubscription := subreaper.Subscribe()
	err = d.startCmd(cmd)
	if err != nil {
		subreaper.Unsubscribe(exitSubscription)
		d.delete()
		return err
	}

	go d.watch(cmd, exitSubscription)

	return nil
}
Beispiel #14
0
// ContainerTop lists the processes running inside of the given
// container by calling ps with the given args, or with the flags
// "-ef" if no args are given.  An error is returned if the container
// is not found, or is not running, or if there are any problems
// running ps, or parsing the output.
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
	if psArgs == "" {
		psArgs = "-ef"
	}

	container, err := daemon.GetContainer(name)
	if err != nil {
		return nil, err
	}

	if !container.IsRunning() {
		return nil, errNotRunning{container.ID}
	}

	if container.IsRestarting() {
		return nil, errContainerIsRestarting(container.ID)
	}

	pids, err := daemon.containerd.GetPidsForContainer(container.ID)
	if err != nil {
		return nil, err
	}

	output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
	if err != nil {
		return nil, fmt.Errorf("Error running ps: %v", err)
	}

	procList := &types.ContainerProcessList{}

	lines := strings.Split(string(output), "\n")
	procList.Titles = strings.Fields(lines[0])

	pidIndex := -1
	for i, name := range procList.Titles {
		if name == "PID" {
			pidIndex = i
		}
	}
	if pidIndex == -1 {
		return nil, fmt.Errorf("Couldn't find PID field in ps output")
	}

	// loop through the output and extract the PID from each line
	for _, line := range lines[1:] {
		if len(line) == 0 {
			continue
		}
		fields := strings.Fields(line)
		p, err := strconv.Atoi(fields[pidIndex])
		if err != nil {
			return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
		}

		for _, pid := range pids {
			if pid == p {
				// Make sure number of fields equals number of header titles
				// merging "overhanging" fields
				process := fields[:len(procList.Titles)-1]
				process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
				procList.Processes = append(procList.Processes, process)
			}
		}
	}
	daemon.LogContainerEvent(container, "top")
	return procList, nil
}