func containerInfo(d *lxd.Client, name string, showLog bool) error { ct, err := d.ContainerStatus(name) if err != nil { return err } fmt.Printf(gettext.Gettext("Name: %s")+"\n", ct.Name) fmt.Printf(gettext.Gettext("Status: %s")+"\n", ct.Status.Status) if ct.Status.Init != 0 { fmt.Printf(gettext.Gettext("Init: %d")+"\n", ct.Status.Init) fmt.Printf(gettext.Gettext("Processcount: %d")+"\n", ct.Status.Processcount) fmt.Printf(gettext.Gettext("Ips:") + "\n") foundone := false for _, ip := range ct.Status.Ips { vethStr := "" if ip.HostVeth != "" { vethStr = fmt.Sprintf("\t%s", ip.HostVeth) } fmt.Printf(" %s:\t%s\t%s%s\n", ip.Interface, ip.Protocol, ip.Address, vethStr) foundone = true } if !foundone { fmt.Println(gettext.Gettext("(none)")) } } // List snapshots first_snapshot := true snaps, err := d.ListSnapshots(name) if err != nil { return nil } for _, snap := range snaps { if first_snapshot { fmt.Println(gettext.Gettext("Snapshots:")) } fmt.Printf(" %s\n", snap) first_snapshot = false } if showLog { log, err := d.GetLog(name, "lxc.log") if err != nil { return err } stuff, err := ioutil.ReadAll(log) if err != nil { return err } fmt.Printf("\n"+gettext.Gettext("Log:")+"\n\n%s\n", string(stuff)) } return nil }
func doConfigEdit(client *lxd.Client, cont string) error { if !terminal.IsTerminal(syscall.Stdin) { contents, err := ioutil.ReadAll(os.Stdin) if err != nil { return err } newdata := shared.BriefContainerState{} err = yaml.Unmarshal(contents, &newdata) if err != nil { return err } return client.UpdateContainerConfig(cont, newdata) } config, err := client.ContainerStatus(cont, false) if err != nil { return err } brief := config.BriefState() editor := os.Getenv("VISUAL") if editor == "" { editor = os.Getenv("EDITOR") if editor == "" { editor = "vi" } } data, err := yaml.Marshal(&brief) f, err := ioutil.TempFile("", "lxd_lxc_config_") 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(configEditHelp)) f.Write(data) f.Close() defer os.Remove(fname) for { cmdParts := strings.Fields(editor) cmd := exec.Command(cmdParts[0], append(cmdParts[1:], 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.BriefContainerState{} 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 = client.UpdateContainerConfig(cont, newdata) break } return err }
func containerInfo(d *lxd.Client, name string, showLog bool) error { ct, err := d.ContainerStatus(name) if err != nil { return err } const layout = "2006/01/02 15:04 UTC" fmt.Printf(i18n.G("Name: %s")+"\n", ct.Name) if ct.CreationDate != 0 { fmt.Printf(i18n.G("Created: %s")+"\n", time.Unix(ct.CreationDate, 0).UTC().Format(layout)) } fmt.Printf(i18n.G("Status: %s")+"\n", ct.Status.Status) if ct.Ephemeral { fmt.Printf(i18n.G("Type: ephemeral") + "\n") } else { fmt.Printf(i18n.G("Type: persistent") + "\n") } fmt.Printf(i18n.G("Profiles: %s")+"\n", strings.Join(ct.Profiles, ", ")) if ct.Status.Init != 0 { fmt.Printf(i18n.G("Init: %d")+"\n", ct.Status.Init) fmt.Printf(i18n.G("Processcount: %d")+"\n", ct.Status.Processcount) fmt.Printf(i18n.G("Ips:") + "\n") foundone := false for _, ip := range ct.Status.Ips { vethStr := "" if ip.HostVeth != "" { vethStr = fmt.Sprintf("\t%s", ip.HostVeth) } fmt.Printf(" %s:\t%s\t%s%s\n", ip.Interface, ip.Protocol, ip.Address, vethStr) foundone = true } if !foundone { fmt.Println(i18n.G("(none)")) } } // List snapshots first_snapshot := true snaps, err := d.ListSnapshots(name) if err != nil { return nil } for _, snap := range snaps { if first_snapshot { fmt.Println(i18n.G("Snapshots:")) } fmt.Printf(" %s", snap.Name) if snap.CreationDate != 0 { fmt.Printf(" ("+i18n.G("taken at %s")+")", time.Unix(snap.CreationDate, 0).UTC().Format(layout)) } if snap.Stateful { fmt.Printf(" (" + i18n.G("stateful") + ")") } else { fmt.Printf(" (" + i18n.G("stateless") + ")") } fmt.Printf("\n") first_snapshot = false } if showLog { log, err := d.GetLog(name, "lxc.log") if err != nil { return err } stuff, err := ioutil.ReadAll(log) if err != nil { return err } fmt.Printf("\n"+i18n.G("Log:")+"\n\n%s\n", string(stuff)) } return nil }
func doConfigEdit(client *lxd.Client, cont string) error { // If stdin isn't a terminal, read text from it if !terminal.IsTerminal(int(syscall.Stdin)) { contents, err := ioutil.ReadAll(os.Stdin) if err != nil { return err } newdata := shared.BriefContainerState{} err = yaml.Unmarshal(contents, &newdata) if err != nil { return err } return client.UpdateContainerConfig(cont, newdata) } // Extract the current value config, err := client.ContainerStatus(cont) if err != nil { return err } brief := config.BriefState() data, err := yaml.Marshal(&brief) if err != nil { return err } // Spawn the editor content, err := shared.TextEditor("", []byte(configEditHelp+"\n\n"+string(data))) if err != nil { return err } for { // Parse the text received from the editor newdata := shared.BriefContainerState{} err = yaml.Unmarshal(content, &newdata) if err == nil { err = client.UpdateContainerConfig(cont, newdata) } // Respawn the editor if err != nil { fmt.Fprintf(os.Stderr, i18n.G("Config parsing error: %s")+"\n", err) fmt.Println(i18n.G("Press enter to start the editor again")) _, err := os.Stdin.Read(make([]byte, 1)) if err != nil { return err } content, err = shared.TextEditor("", content) if err != nil { return err } continue } break } return nil }