func Main() { cfg := config.LoadConfig() execID, resp, err := startDocker(cfg) if err != nil { log.Fatal(err) } process, err := getDockerProcess() if err != nil { log.Fatal(err) } handleTerm(process) // Wait for Docker daemon to exit io.Copy(ioutil.Discard, resp.Reader) resp.Close() client, err := rosDocker.NewSystemClient() if err != nil { log.Fatal(err) } state, err := client.ContainerExecInspect(context.Background(), execID) if err != nil { log.Fatal(err) } // Proxy exit code os.Exit(state.ExitCode) }
func osMetaDataGet(c *cli.Context) { images, err := getImages() if err != nil { log.Fatal(err) } client, err := docker.NewSystemClient() if err != nil { log.Fatal(err) } for _, image := range images.Available { _, err := client.InspectImage(image) if err == dockerClient.ErrNoSuchImage { fmt.Println(image, "remote") } else { fmt.Println(image, "local") } } }
func loadImages(cfg *config.CloudConfig) (*config.CloudConfig, error) { images, err := findImages(cfg) if err != nil || len(images) == 0 { return cfg, err } client, err := docker.NewSystemClient() if err != nil { return cfg, err } for _, image := range images { if hasImage(image) { continue } inputFileName := path.Join(config.IMAGES_PATH, image) input, err := os.Open(inputFileName) if err != nil { return cfg, err } defer input.Close() log.Infof("Loading images from %s", inputFileName) err = client.LoadImage(dockerClient.LoadImageOptions{ InputStream: input, }) if err != nil { return cfg, err } log.Infof("Done loading images from %s", inputFileName) } return cfg, nil }
func runDocker(name string) error { if os.ExpandEnv("${IN_DOCKER}") == "true" { return nil } client, err := docker.NewSystemClient() if err != nil { return err } cmd := []string{name} if name == "" { name = filepath.Base(os.Args[0]) cmd = os.Args } existing, err := client.ContainerInspect(context.Background(), name) if err == nil && existing.ID != "" { err := client.ContainerRemove(context.Background(), types.ContainerRemoveOptions{ ContainerID: existing.ID, }) if err != nil { return err } } currentContainerId, err := util.GetCurrentContainerId() if err != nil { return err } currentContainer, err := client.ContainerInspect(context.Background(), currentContainerId) if err != nil { return err } powerContainer, err := client.ContainerCreate(context.Background(), &container.Config{ Image: currentContainer.Config.Image, Cmd: cmd, Env: []string{ "IN_DOCKER=true", }, }, &container.HostConfig{ PidMode: "host", VolumesFrom: []string{ currentContainer.ID, }, Privileged: true, }, nil, name) if err != nil { return err } go func() { client.ContainerAttach(context.Background(), types.ContainerAttachOptions{ ContainerID: powerContainer.ID, Stream: true, Stderr: true, Stdout: true, }) }() err = client.ContainerStart(context.Background(), powerContainer.ID) if err != nil { return err } _, err = client.ContainerWait(context.Background(), powerContainer.ID) if err != nil { log.Fatal(err) } os.Exit(0) return nil }
func shutDownContainers() error { var err error shutDown := true timeout := 2 for i, arg := range os.Args { if arg == "-f" || arg == "--f" || arg == "--force" { shutDown = false } if arg == "-t" || arg == "--t" || arg == "--timeout" { if len(os.Args) > i+1 { t, err := strconv.Atoi(os.Args[i+1]) if err != nil { return err } timeout = t } else { log.Error("please specify a timeout") } } } if !shutDown { return nil } client, err := docker.NewSystemClient() if err != nil { return err } filter := filters.NewArgs() filter.Add("status", "running") opts := types.ContainerListOptions{ All: true, Filter: filter, } containers, err := client.ContainerList(context.Background(), opts) if err != nil { return err } currentContainerId, err := util.GetCurrentContainerId() if err != nil { return err } var stopErrorStrings []string for _, container := range containers { if container.ID == currentContainerId { continue } log.Infof("Stopping %s : %v", container.ID[:12], container.Names) stopErr := client.ContainerStop(context.Background(), container.ID, timeout) if stopErr != nil { stopErrorStrings = append(stopErrorStrings, " ["+container.ID+"] "+stopErr.Error()) } } var waitErrorStrings []string for _, container := range containers { if container.ID == currentContainerId { continue } _, waitErr := client.ContainerWait(context.Background(), container.ID) if waitErr != nil { waitErrorStrings = append(waitErrorStrings, " ["+container.ID+"] "+waitErr.Error()) } } if len(waitErrorStrings) != 0 || len(stopErrorStrings) != 0 { return errors.New("error while stopping \n1. STOP Errors [" + strings.Join(stopErrorStrings, ",") + "] \n2. WAIT Errors [" + strings.Join(waitErrorStrings, ",") + "]") } return nil }
func startUpgradeContainer(image string, stage, force, reboot, kexec bool, kernelArgs string) error { in := bufio.NewReader(os.Stdin) command := []string{ "-t", "rancher-upgrade", "-r", config.VERSION, } if kexec { command = append(command, "-k") kernelArgs = strings.TrimSpace(kernelArgs) if kernelArgs != "" { command = append(command, "-a", kernelArgs) } } container, err := compose.CreateService(nil, "os-upgrade", &project.ServiceConfig{ LogDriver: "json-file", Privileged: true, Net: "host", Pid: "host", Image: image, Labels: project.NewSliceorMap(map[string]string{ config.SCOPE: config.SYSTEM, }), Command: project.NewCommand(command...), }) if err != nil { return err } client, err := docker.NewSystemClient() if err != nil { return err } // Only pull image if not found locally if _, err := client.InspectImage(image); err != nil { if err := container.Pull(); err != nil { return err } } if !stage { imageSplit := strings.Split(image, ":") if len(imageSplit) > 1 && imageSplit[1] == config.VERSION { if !force && !yes(in, fmt.Sprintf("Already at version %s. Continue anyways", imageSplit[1])) { os.Exit(1) } } else { fmt.Printf("Upgrading to %s\n", image) if !force && !yes(in, "Continue") { os.Exit(1) } } // If there is already an upgrade container, delete it // Up() should to this, but currently does not due to a bug if err := container.Delete(); err != nil { return err } if err := container.Up(); err != nil { return err } if err := container.Log(); err != nil { return err } if err := container.Delete(); err != nil { return err } if reboot && (force || yes(in, "Continue with reboot")) { log.Info("Rebooting") power.Reboot() } } return nil }
func runDocker(name string) error { if os.ExpandEnv("${IN_DOCKER}") == "true" { return nil } client, err := docker.NewSystemClient() if err != nil { return err } cmd := []string{name} if name == "" { name = filepath.Base(os.Args[0]) cmd = os.Args } exiting, err := client.InspectContainer(name) if exiting != nil { err := client.RemoveContainer(dockerClient.RemoveContainerOptions{ ID: exiting.ID, Force: true, }) if err != nil { return err } } currentContainerId, err := getCurrentContainerId() if err != nil { return err } currentContainer, err := client.InspectContainer(currentContainerId) if err != nil { return err } powerContainer, err := client.CreateContainer(dockerClient.CreateContainerOptions{ Name: name, Config: &dockerClient.Config{ Image: currentContainer.Config.Image, Cmd: cmd, Env: []string{ "IN_DOCKER=true", }, }, HostConfig: &dockerClient.HostConfig{ PidMode: "host", VolumesFrom: []string{ currentContainer.ID, }, Privileged: true, }, }) if err != nil { return err } go func() { client.AttachToContainer(dockerClient.AttachToContainerOptions{ Container: powerContainer.ID, OutputStream: os.Stdout, ErrorStream: os.Stderr, Stderr: true, Stdout: true, }) }() err = client.StartContainer(powerContainer.ID, powerContainer.HostConfig) if err != nil { return err } _, err = client.WaitContainer(powerContainer.ID) if err != nil { log.Fatal(err) } os.Exit(0) return nil }
func startDocker(cfg *config.CloudConfig) (string, types.HijackedResponse, error) { storageContext := cfg.Rancher.Docker.StorageContext if storageContext == "" { storageContext = DEFAULT_STORAGE_CONTEXT } log.Infof("Starting Docker in context: %s", storageContext) p, err := compose.GetProject(cfg, true, false) if err != nil { return "", types.HijackedResponse{}, err } pid, err := waitForPid(storageContext, p) if err != nil { return "", types.HijackedResponse{}, err } log.Infof("%s PID %d", storageContext, pid) client, err := rosDocker.NewSystemClient() if err != nil { return "", types.HijackedResponse{}, err } if err := os.Remove(DOCKER_PID_FILE); err != nil && !os.IsNotExist(err) { return "", types.HijackedResponse{}, err } dockerCfg := cfg.Rancher.Docker args := dockerCfg.FullArgs() log.Debugf("User Docker args: %v", args) if dockerCfg.TLS { if err := writeCerts(cfg); err != nil { return "", types.HijackedResponse{}, err } } cmd := []string{"env"} log.Info(dockerCfg.AppendEnv()) cmd = append(cmd, dockerCfg.AppendEnv()...) cmd = append(cmd, DOCKER_COMMAND) cmd = append(cmd, args...) log.Infof("Running %v", cmd) resp, err := client.ContainerExecCreate(context.Background(), types.ExecConfig{ Container: storageContext, Privileged: true, AttachStderr: true, AttachStdout: true, Cmd: cmd, }) if err != nil { return "", types.HijackedResponse{}, err } attachResp, err := client.ContainerExecAttach(context.Background(), resp.ID, types.ExecConfig{ Detach: false, AttachStderr: true, AttachStdout: true, }) if err != nil { return "", types.HijackedResponse{}, err } return resp.ID, attachResp, nil }