func showImages(images []shared.ImageInfo) error { data := [][]string{} for _, image := range images { shortest := shortestAlias(image.Aliases) if len(image.Aliases) > 1 { shortest = fmt.Sprintf("%s (%d more)", shortest, len(image.Aliases)-1) } fp := image.Fingerprint[0:12] public := "no" description := findDescription(image.Properties) if image.Public == 1 { public = "yes" } const layout = "Jan 2, 2006 at 3:04pm (MST)" uploaded := time.Unix(image.UploadDate, 0).Format(layout) arch, _ := shared.ArchitectureName(image.Architecture) data = append(data, []string{shortest, fp, public, description, arch, uploaded}) } table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"ALIAS", "FINGERPRINT", "PUBLIC", "DESCRIPTION", "ARCH", "UPLOAD DATE"}) for _, v := range data { table.Append(v) } table.Render() return nil }
func (c *imageCmd) run(config *lxd.Config, args []string) error { var remote string if len(args) < 1 { return errArgs } switch args[0] { case "alias": if len(args) < 2 { return errArgs } return doImageAlias(config, args) case "copy": /* copy [<remote>:]<image> [<rmeote>:]<image> */ if len(args) != 3 { return errArgs } remote, inName := config.ParseRemoteAndContainer(args[1]) if inName == "" { return errArgs } destRemote, outName := config.ParseRemoteAndContainer(args[2]) if outName != "" { return errArgs } d, err := lxd.NewClient(config, remote) if err != nil { return err } dest, err := lxd.NewClient(config, destRemote) if err != nil { return err } image := dereferenceAlias(d, inName) return d.CopyImage(image, dest, copyAliases, addAliases, publicImage) case "delete": /* delete [<remote>:]<image> */ if len(args) < 2 { return errArgs } remote, inName := config.ParseRemoteAndContainer(args[1]) if inName == "" { return errArgs } d, err := lxd.NewClient(config, remote) if err != nil { return err } image := dereferenceAlias(d, inName) err = d.DeleteImage(image) return err case "info": if len(args) < 2 { return errArgs } remote, inName := config.ParseRemoteAndContainer(args[1]) if inName == "" { return errArgs } d, err := lxd.NewClient(config, remote) if err != nil { return err } image := dereferenceAlias(d, inName) info, err := d.GetImageInfo(image) if err != nil { return err } fmt.Printf(gettext.Gettext("Fingerprint: %s\n"), info.Fingerprint) public := "no" if info.Public == 1 { public = "yes" } fmt.Printf(gettext.Gettext("Size: %.2vMB\n"), float64(info.Size)/1024.0/1024.0) arch, _ := shared.ArchitectureName(info.Architecture) fmt.Printf(gettext.Gettext("Architecture: %s\n"), arch) fmt.Printf(gettext.Gettext("Public: %s\n"), public) fmt.Printf(gettext.Gettext("Timestamps:\n")) const layout = "2006/01/02 15:04 UTC" if info.CreationDate != 0 { fmt.Printf(" Created: %s\n", time.Unix(info.CreationDate, 0).UTC().Format(layout)) } fmt.Printf(" Uploaded: %s\n", time.Unix(info.UploadDate, 0).UTC().Format(layout)) if info.ExpiryDate != 0 { fmt.Printf(" Expires: %s\n", time.Unix(info.ExpiryDate, 0).UTC().Format(layout)) } else { fmt.Printf(" Expires: never\n") } fmt.Printf(gettext.Gettext("Properties:\n")) for key, value := range info.Properties { fmt.Printf(" %s: %s\n", key, value) } fmt.Printf(gettext.Gettext("Aliases:\n")) for _, alias := range info.Aliases { fmt.Printf(" - %s\n", alias.Name) } return nil case "import": if len(args) < 2 { return errArgs } imagefile := args[1] var properties []string if len(args) > 2 { split := strings.Split(args[2], "=") if len(split) == 1 { remote, _ = config.ParseRemoteAndContainer(args[2]) if len(args) > 3 { properties = args[3:] } else { properties = []string{} } } else { properties = args[2:] } } else { remote = "" properties = []string{} } d, err := lxd.NewClient(config, remote) if err != nil { return err } fingerprint, err := d.PostImage(imagefile, properties, publicImage, addAliases) if err != nil { return err } fmt.Printf(gettext.Gettext("Image imported with fingerprint: %s\n"), fingerprint) return nil case "list": if len(args) > 1 { remote, _ = config.ParseRemoteAndContainer(args[1]) } else { remote = "" } d, err := lxd.NewClient(config, remote) if err != nil { return err } images, err := d.ListImages() if err != nil { return err } return showImages(images) case "edit": if len(args) < 2 { return errArgs } remote, inName := config.ParseRemoteAndContainer(args[1]) if inName == "" { return errArgs } d, err := lxd.NewClient(config, remote) if err != nil { return err } image := dereferenceAlias(d, inName) if image == "" { image = inName } if !terminal.IsTerminal(syscall.Stdin) { contents, err := ioutil.ReadAll(os.Stdin) if err != nil { return err } newdata := shared.ImageProperties{} err = yaml.Unmarshal(contents, &newdata) if err != nil { return err } return d.PutImageProperties(image, newdata) } info, err := d.GetImageInfo(image) if err != nil { return err } properties := info.Properties editor := os.Getenv("VISUAL") if editor == "" { editor = os.Getenv("EDITOR") if editor == "" { editor = "vi" } } data, err := yaml.Marshal(&properties) f, err := ioutil.TempFile("", "lxd_lxc_image_") if err != nil { return err } fname := f.Name() if err = f.Chmod(0600); err != nil { f.Close() os.Remove(fname) return err } f.Write([]byte(imageEditHelp)) f.Write(data) f.Close() defer os.Remove(fname) for { cmd := exec.Command(editor, fname) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return err } contents, err := ioutil.ReadFile(fname) if err != nil { return err } newdata := shared.ImageProperties{} err = yaml.Unmarshal(contents, &newdata) if err != nil { fmt.Fprintf(os.Stderr, gettext.Gettext("YAML parse error %v\n"), err) fmt.Printf("Press enter to play again ") _, err := os.Stdin.Read(make([]byte, 1)) if err != nil { return err } continue } err = d.PutImageProperties(image, newdata) break } return err case "export": if len(args) < 2 { return errArgs } remote, inName := config.ParseRemoteAndContainer(args[1]) if inName == "" { return errArgs } d, err := lxd.NewClient(config, remote) if err != nil { return err } image := dereferenceAlias(d, inName) target := "." if len(args) > 2 { target = args[2] } _, outfile, err := d.ExportImage(image, target) if err != nil { return err } if target != "-" { fmt.Printf("Output is in %s\n", outfile) } return nil case "show": if len(args) < 2 { return errArgs } remote, inName := config.ParseRemoteAndContainer(args[1]) if inName == "" { return errArgs } d, err := lxd.NewClient(config, remote) if err != nil { return err } image := dereferenceAlias(d, inName) info, err := d.GetImageInfo(image) if err != nil { return err } properties := info.Properties data, err := yaml.Marshal(&properties) fmt.Printf("%s", data) return err default: return fmt.Errorf(gettext.Gettext("Unknown image command %s"), args[0]) } }