func startUpgradeContainer(image string, stage, force, reboot, kexec bool) error { in := bufio.NewReader(os.Stdin) command := []string{ "-t", "rancher-upgrade", "-r", config.VERSION, } if kexec { command = append(command, "-k") } 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 } if err := container.Pull(); err != nil { return err } if !stage { fmt.Printf("Upgrading to %s\n", image) if !force { if !yes(in, "Continue") { os.Exit(1) } } 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 }
// Run implements Service.Run. It runs a one of command within the service container. func (s *Service) Run(commandParts []string) (int, error) { imageName, err := s.ensureImageExists() if err != nil { return -1, err } client := s.context.ClientFactory.Create(s) namer := NewNamer(client, s.context.Project.Name, s.name+"_run") defer namer.Close() containerName := namer.Next() c := NewContainer(client, containerName, s) return c.Run(imageName, &project.ServiceConfig{Command: project.NewCommand(commandParts...), Tty: true, StdinOpen: true}) }
func (s *Service) Run(commandParts []string) (int, error) { var err error client := s.context.ClientFactory.Create(s) namer := NewNamer(client, s.context.Project.Name, s.name+"_run") defer namer.Close() containerName := namer.Next() c := NewContainer(client, containerName, s) imageName, err := s.build() if err != nil { return 1, err } container, err := c.CreateWithOverride(imageName, &project.ServiceConfig{Command: project.NewCommand(commandParts...), Tty: true}) if err != nil { return 1, err } info, err := c.client.InspectContainer(container.Id) if err != nil { return 1, err } err = c.Start(container, info.HostConfig) if err != nil { return 1, err } err = c.Log() if err != nil { return 1, err } info, err = c.client.InspectContainer(container.Id) if err != nil { return 1, err } return info.State.ExitCode, nil }
func TestParseBindsAndVolumes(t *testing.T) { bashCmd := "bash" fooLabel := "foo.label" fooLabelValue := "service.config.value" sc := &project.ServiceConfig{ Entrypoint: project.NewCommand(bashCmd), Volumes: []string{"/foo", "/home:/home", "/bar/baz", "/usr/lib:/usr/lib:ro"}, Labels: project.NewSliceorMap(map[string]string{fooLabel: "service.config.value"}), } cfg, hostCfg, err := Convert(sc) assert.Nil(t, err) assert.Equal(t, map[string]struct{}{"/foo": {}, "/bar/baz": {}}, cfg.Volumes) assert.Equal(t, []string{"/home:/home", "/usr/lib:/usr/lib:ro"}, hostCfg.Binds) cfg.Labels[fooLabel] = "FUN" cfg.Entrypoint[0] = "less" assert.Equal(t, fooLabelValue, sc.Labels.MapParts()[fooLabel]) assert.Equal(t, "FUN", cfg.Labels[fooLabel]) assert.Equal(t, []string{bashCmd}, sc.Entrypoint.Slice()) assert.Equal(t, []string{"less"}, cfg.Entrypoint) }
func TestParseLabels(t *testing.T) { ctx := &Context{} ctx.ComposeFiles = []string{"foo/docker-compose.yml"} ctx.ResourceLookup = &lookup.FileConfigLookup{} bashCmd := "bash" fooLabel := "foo.label" fooLabelValue := "service.config.value" sc := &project.ServiceConfig{ Entrypoint: project.NewCommand(bashCmd), Labels: project.NewSliceorMap(map[string]string{fooLabel: "service.config.value"}), } cfg, _, err := Convert(sc, ctx) assert.Nil(t, err) cfg.Labels[fooLabel] = "FUN" cfg.Entrypoint[0] = "less" assert.Equal(t, fooLabelValue, sc.Labels.MapParts()[fooLabel]) assert.Equal(t, "FUN", cfg.Labels[fooLabel]) assert.Equal(t, []string{bashCmd}, sc.Entrypoint.Slice()) assert.Equal(t, []string{"less"}, cfg.Entrypoint) }
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 }