func upload(args *docopt.Args) { tag := args.String["<tag>"] if tag == "" { tag = "latest" } var manifest map[string]string if err := cliutil.DecodeJSONArg(args.String["<manifest>"], &manifest); err != nil { log.Fatal(err) } for image, id := range manifest { u, err := url.Parse(image) if err != nil { log.Fatal(err) } var tagged string if u.Host == defaultRegistry { tagged = u.Path[1:] + ":" + tag } else { tagged = u.Host + u.Path + ":" + tag } run(exec.Command("docker", "tag", id, tagged)) fmt.Println("Tagged", tagged) fmt.Printf("Uploading %s...\n", tagged) run(exec.Command("docker", "push", tagged)) } }
func export(args *docopt.Args) { var manifest map[string]string if err := cliutil.DecodeJSONArg(args.String["<manifest>"], &manifest); err != nil { log.Fatal(err) } reg := registry.Registry{Path: args.String["<dir>"]} if err := reg.Init(); err != nil { log.Fatal(err) } images := make([]string, 0, len(manifest)) for name, id := range manifest { tagged := name + ":latest" run(exec.Command("docker", "tag", "--force", id, tagged)) images = append(images, tagged) } cmd := exec.Command("docker", append([]string{"save"}, images...)...) cmd.Stderr = os.Stderr out, err := cmd.StdoutPipe() if err != nil { log.Fatal(err) } if err := cmd.Start(); err != nil { log.Fatal(err) } if err := registry.ExtractTarWithoutTarsums(®, out); err != nil { log.Fatal(err) } if err := cmd.Wait(); err != nil { log.Fatal(err) } }
func export(args *docopt.Args) { log := log15.New() log.Info("decoding manifest") var manifest map[string]*ct.Artifact if err := cliutil.DecodeJSONArg(args.String["<manifest>"], &manifest); err != nil { log.Error("error decoding manifest", "err", err) os.Exit(1) } exporter := Exporter{ dir: args.String["<dir>"], log: log15.New(), } log.Info(fmt.Sprintf("exporting %d images to %s", len(manifest), exporter.dir)) if err := exporter.Export(manifest); err != nil { log.Error("error exporting images", "err", err) os.Exit(1) } }
func runDownload(args *docopt.Args) error { if err := os.MkdirAll(args.String["--root"], 0755); err != nil { return fmt.Errorf("error creating root dir: %s", err) } var manifest map[string]string if err := cliutil.DecodeJSONArg(args.String["<manifest>"], &manifest); err != nil { return err } ctx, err := pinkerton.BuildContext(args.String["--driver"], args.String["--root"]) if err != nil { return err } for image, id := range manifest { fmt.Printf("Downloading %s %s...\n", image, id) image += "?id=" + id if err := ctx.Pull(image, pinkerton.InfoPrinter(false)); err != nil { return err } } return nil }
func runRun(args *docopt.Args, client *cluster.Client) error { artifact := &ct.Artifact{} if err := cliutil.DecodeJSONArg(args.String["<artifact>"], artifact); err != nil { return err } cmd := exec.Cmd{ ImageArtifact: artifact, Job: &host.Job{ Config: host.ContainerConfig{ Args: append([]string{args.String["<command>"]}, args.All["<argument>"].([]string)...), TTY: term.IsTerminal(os.Stdin.Fd()) && term.IsTerminal(os.Stdout.Fd()), Stdin: true, DisableLog: true, }, }, HostID: args.String["--host"], Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, } if cmd.Job.Config.TTY { ws, err := term.GetWinsize(os.Stdin.Fd()) if err != nil { return err } cmd.TermHeight = ws.Height cmd.TermWidth = ws.Width cmd.Env = map[string]string{ "COLUMNS": strconv.Itoa(int(ws.Width)), "LINES": strconv.Itoa(int(ws.Height)), "TERM": os.Getenv("TERM"), } } if specs := args.String["--bind"]; specs != "" { mounts := strings.Split(specs, ",") cmd.Job.Config.Mounts = make([]host.Mount, len(mounts)) for i, m := range mounts { s := strings.SplitN(m, ":", 2) cmd.Job.Config.Mounts[i] = host.Mount{ Target: s[0], Location: s[1], Writeable: true, } } } var termState *term.State if cmd.Job.Config.TTY { var err error termState, err = term.MakeRaw(os.Stdin.Fd()) if err != nil { return err } // Restore the terminal if we return without calling os.Exit defer term.RestoreTerminal(os.Stdin.Fd(), termState) go func() { ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGWINCH) for range ch { ws, err := term.GetWinsize(os.Stdin.Fd()) if err != nil { return } cmd.ResizeTTY(ws.Height, ws.Width) cmd.Signal(int(syscall.SIGWINCH)) } }() } go func() { ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) sig := <-ch cmd.Signal(int(sig.(syscall.Signal))) time.Sleep(10 * time.Second) cmd.Signal(int(syscall.SIGKILL)) }() err := cmd.Run() if status, ok := err.(exec.ExitError); ok { if cmd.Job.Config.TTY { // The deferred restore doesn't happen due to the exit below term.RestoreTerminal(os.Stdin.Fd(), termState) } os.Exit(int(status)) } return err }