func runTorContainer(cli *client.Client, ident, imageID, network string) (string, error) { config := &types.ContainerCreateConfig{ Name: ident, Config: &containerTypes.Config{ Image: imageID, }, } resp, err := cli.ContainerCreate(config.Config, config.HostConfig, config.NetworkingConfig, config.Name) if err != nil { return "", err } // TODO: Remove container on failure. for _, warning := range resp.Warnings { log.Warn(warning) } if err := cli.ContainerStart(resp.ID); err != nil { return "", err } // Connect to the network. if err := cli.NetworkConnect(network, resp.ID, nil); err != nil { return "", err } return resp.ID, err }
// runs a command in a container , with volume mounted // returns completion code. // exits (t.Fatal() or create/start/wait errors func runContainerCmd(t *testing.T, client *client.Client, volumeName string, image string, cmd *strslice.StrSlice, addr string) int { mountPoint := getMountpoint(volumeName) bind := volumeName + ":" + mountPoint t.Logf("Running cmd=%v with vol=%s on client %s", cmd, volumeName, addr) r, err := client.ContainerCreate(context.Background(), &container.Config{Image: image, Cmd: *cmd, Volumes: map[string]struct{}{mountPoint: {}}}, &container.HostConfig{Binds: []string{bind}}, nil, "") if err != nil { t.Fatalf("\tContainer create failed: %v", err) } err = client.ContainerStart(context.Background(), r.ID, types.ContainerStartOptions{}) if err != nil { t.Fatalf("\tContainer start failed: id=%s, err %v", r.ID, err) } code, err := client.ContainerWait(context.Background(), r.ID) if err != nil { t.Fatalf("\tContainer wait failed: id=%s, err %v", r.ID, err) } if removeContainers == false { t.Logf("\tSkipping container removal, id=%s (removeContainers == false)", r.ID) return code } err = client.ContainerRemove(context.Background(), r.ID, types.ContainerRemoveOptions{ RemoveVolumes: true, Force: true, }) if err != nil { t.Fatalf("\nContainer removal failed: %v", err) } return code }
func newContainer(ctx context.Context, client *client.Client, profile *Profile, name, executable string, args, env map[string]string) (pr *process, err error) { defer apexctx.GetLogger(ctx).Trace("spawning container").Stop(&err) var image string if registry := profile.Registry; registry != "" { image = registry + "/" + name } else { image = name } var Env = make([]string, 0, len(env)) for k, v := range env { Env = append(Env, k+"="+v) } var binds = make([]string, 1, len(profile.Binds)+1) binds[0] = filepath.Dir(args["--endpoint"]) + ":" + profile.RuntimePath binds = append(binds, profile.Binds...) // update args["--endpoint"] according to the container's point of view args["--endpoint"] = filepath.Join(profile.RuntimePath, filepath.Base(args["--endpoint"])) var Cmd = make(strslice.StrSlice, 1, len(args)+1) Cmd[0] = executable for k, v := range args { Cmd = append(Cmd, k, v) } config := container.Config{ AttachStdin: false, AttachStdout: true, AttachStderr: true, Env: Env, Cmd: Cmd, Image: image, WorkingDir: profile.Cwd, Labels: map[string]string{isolateDockerLabel: name}, } apexctx.GetLogger(ctx).Info("applying Resource limits") var resources = container.Resources{ Memory: profile.Resources.Memory, CPUShares: profile.Resources.CPUShares, CPUPeriod: profile.Resources.CPUPeriod, CPUQuota: profile.Resources.CPUQuota, CpusetCpus: profile.Resources.CpusetCpus, CpusetMems: profile.Resources.CpusetMems, } hostConfig := container.HostConfig{ NetworkMode: profile.NetworkMode, Binds: binds, Resources: resources, } if len(profile.Tmpfs) != 0 { buff := new(bytes.Buffer) for k, v := range profile.Tmpfs { fmt.Fprintf(buff, "%s: %s;", k, v) } apexctx.GetLogger(ctx).Infof("mounting `tmpfs` to container: %s", buff.String()) hostConfig.Tmpfs = profile.Tmpfs } // NOTE: It should be nil var networkingConfig *network.NetworkingConfig resp, err := client.ContainerCreate(ctx, &config, &hostConfig, networkingConfig, "") if err != nil { apexctx.GetLogger(ctx).WithError(err).Error("unable to create a container") return nil, err } for _, warn := range resp.Warnings { apexctx.GetLogger(ctx).Warnf("%s warning: %s", resp.ID, warn) } ctx, cancel := context.WithCancel(ctx) pr = &process{ ctx: ctx, cancellation: cancel, client: client, containerID: resp.ID, } return pr, nil }