Ejemplo n.º 1
0
Archivo: list.go Proyecto: hex2a/lxd
func isEphemeralColumnData(cinfo shared.ContainerInfo) string {
	if cinfo.State.Ephemeral {
		return i18n.G("YES")
	} else {
		return i18n.G("NO")
	}
}
Ejemplo n.º 2
0
Archivo: main.go Proyecto: HPCNow/lxd
func main() {
	if err := run(); err != nil {
		// The action we take depends on the error we get.
		msg := fmt.Sprintf(i18n.G("error: %v"), err)
		switch t := err.(type) {
		case *url.Error:
			switch u := t.Err.(type) {
			case *net.OpError:
				if u.Op == "dial" && u.Net == "unix" {
					switch errno := u.Err.(type) {
					case syscall.Errno:
						switch errno {
						case syscall.ENOENT:
							msg = i18n.G("LXD socket not found; is LXD running?")
						case syscall.ECONNREFUSED:
							msg = i18n.G("Connection refused; is LXD running?")
						case syscall.EACCES:
							msg = i18n.G("Permisson denied, are you in the lxd group?")
						default:
							msg = fmt.Sprintf("%d %s", uintptr(errno), errno.Error())
						}
					}
				}
			}
		}

		fmt.Fprintln(os.Stderr, fmt.Sprintf("%s", msg))
		os.Exit(1)
	}
}
Ejemplo n.º 3
0
Archivo: main.go Proyecto: HPCNow/lxd
func execIfAliases(config *lxd.Config, origArgs []string) {
	newArgs := []string{}
	expandedAlias := false
	for _, arg := range origArgs {
		changed := false
		for k, v := range config.Aliases {
			if k == arg {
				expandedAlias = true
				changed = true
				newArgs = append(newArgs, strings.Split(v, " ")...)
				break
			}
		}

		if !changed {
			newArgs = append(newArgs, arg)
		}
	}

	if expandedAlias {
		path, err := exec.LookPath(origArgs[0])
		if err != nil {
			fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), err)
			os.Exit(5)
		}
		ret := syscall.Exec(path, newArgs, syscall.Environ())
		fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), ret)
		os.Exit(5)
	}
}
Ejemplo n.º 4
0
func (c *actionCmd) run(config *lxd.Config, args []string) error {
	if len(args) == 0 {
		return errArgs
	}

	for _, nameArg := range args {
		remote, name := config.ParseRemoteAndContainer(nameArg)
		d, err := lxd.NewClient(config, remote)
		if err != nil {
			return err
		}

		resp, err := d.Action(name, c.action, timeout, force)
		if err != nil {
			return err
		}

		if resp.Type != lxd.Async {
			return fmt.Errorf(i18n.G("bad result type from action"))
		}

		if err := d.WaitForSuccess(resp.Operation); err != nil {
			return fmt.Errorf("%s\n"+i18n.G("Try `lxc info --show-log %s` for more info"), err, name)
		}
	}
	return nil
}
Ejemplo n.º 5
0
Archivo: client.go Proyecto: djibi2/lxd
func (c *Client) ProfileDeviceAdd(profile, devname, devtype string, props []string) (*Response, error) {
	st, err := c.ProfileConfig(profile)
	if err != nil {
		return nil, err
	}

	newdev := shared.Device{}
	for _, p := range props {
		results := strings.SplitN(p, "=", 2)
		if len(results) != 2 {
			return nil, fmt.Errorf(i18n.G("no value found in %q"), p)
		}
		k := results[0]
		v := results[1]
		newdev[k] = v
	}
	if st.Devices != nil && st.Devices.ContainsName(devname) {
		return nil, fmt.Errorf(i18n.G("device already exists"))
	}
	newdev["type"] = devtype
	if st.Devices == nil {
		st.Devices = shared.Devices{}
	}
	st.Devices[devname] = newdev

	body := shared.Jmap{"config": st.Config, "name": st.Name, "devices": st.Devices}
	return c.put(fmt.Sprintf("profiles/%s", profile), body, Sync)
}
Ejemplo n.º 6
0
Archivo: client.go Proyecto: djibi2/lxd
func (c *Client) UserAuthServerCert(name string, acceptCert bool) error {
	if !c.scertDigestSet {
		if err := c.Finger(); err != nil {
			return err
		}

		if !c.scertDigestSet {
			return fmt.Errorf(i18n.G("No certificate on this connection"))
		}
	}

	if c.scert != nil {
		return nil
	}

	_, err := c.scertWire.Verify(x509.VerifyOptions{
		DNSName:       name,
		Intermediates: c.scertIntermediates,
	})
	if err == nil {
		// Server trusted by system certificate
		return nil
	}

	if acceptCert == false {
		fmt.Printf(i18n.G("Certificate fingerprint: %x")+"\n", c.scertDigest)
		fmt.Printf(i18n.G("ok (y/n)?") + " ")
		line, err := shared.ReadStdin()
		if err != nil {
			return err
		}

		if len(line) < 1 || line[0] != 'y' && line[0] != 'Y' {
			return fmt.Errorf(i18n.G("Server certificate NACKed by user"))
		}
	}

	// User acked the cert, now add it to our store
	dnam := c.Config.ConfigPath("servercerts")
	err = os.MkdirAll(dnam, 0750)
	if err != nil {
		return fmt.Errorf(i18n.G("Could not create server cert dir"))
	}
	certf := fmt.Sprintf("%s/%s.crt", dnam, c.Name)
	certOut, err := os.Create(certf)
	if err != nil {
		return err
	}

	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: c.scertWire.Raw})

	certOut.Close()
	return err
}
Ejemplo n.º 7
0
func doProfileApply(client *lxd.Client, c string, p string) error {
	resp, err := client.ApplyProfile(c, p)
	if err == nil {
		if p == "" {
			p = i18n.G("(none)")
		}
		fmt.Printf(i18n.G("Profile %s applied to %s")+"\n", p, c)
	} else {
		return err
	}
	return client.WaitForSuccess(resp.Operation)
}
Ejemplo n.º 8
0
Archivo: delete.go Proyecto: hex2a/lxd
func (c *deleteCmd) run(config *lxd.Config, args []string) error {
	if len(args) == 0 {
		return errArgs
	}

	for _, nameArg := range args {
		remote, name := config.ParseRemoteAndContainer(nameArg)

		d, err := lxd.NewClient(config, remote)
		if err != nil {
			return err
		}

		if shared.IsSnapshot(name) {
			return c.doDelete(d, name)
		}

		ct, err := d.ContainerStatus(name)
		if err != nil {
			return err
		}

		if ct.Status.StatusCode != 0 && ct.Status.StatusCode != shared.Stopped {
			if !c.force {
				return fmt.Errorf(i18n.G("The container is currently running, stop it first or pass --force."))
			}

			resp, err := d.Action(name, shared.Stop, -1, true)
			if err != nil {
				return err
			}

			op, err := d.WaitFor(resp.Operation)
			if err != nil {
				return err
			}

			if op.StatusCode == shared.Failure {
				return fmt.Errorf(i18n.G("Stopping container failed!"))
			}

			if ct.Ephemeral == true {
				return nil
			}
		}

		if err := c.doDelete(d, name); err != nil {
			return err
		}
	}
	return nil
}
Ejemplo n.º 9
0
Archivo: main.go Proyecto: hex2a/lxd
func execIfAliases(config *lxd.Config, origArgs []string) {
	newArgs, expanded := expandAlias(config, origArgs)
	if !expanded {
		return
	}

	path, err := exec.LookPath(origArgs[0])
	if err != nil {
		fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), err)
		os.Exit(5)
	}
	ret := syscall.Exec(path, newArgs, syscall.Environ())
	fmt.Fprintf(os.Stderr, i18n.G("processing aliases failed %s\n"), ret)
	os.Exit(5)
}
Ejemplo n.º 10
0
func (c *snapshotCmd) run(config *lxd.Config, args []string) error {
	if len(args) < 1 {
		return errArgs
	}

	var snapname string
	if len(args) < 2 {
		snapname = ""
	} else {
		snapname = args[1]
	}

	remote, name := config.ParseRemoteAndContainer(args[0])
	d, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	// we don't allow '/' in snapshot names
	if shared.IsSnapshot(snapname) {
		return fmt.Errorf(i18n.G("'/' not allowed in snapshot name"))
	}

	resp, err := d.Snapshot(name, snapname, c.stateful)
	if err != nil {
		return err
	}

	return d.WaitForSuccess(resp.Operation)
}
Ejemplo n.º 11
0
func (c *profileCmd) usage() string {
	return i18n.G(
		`Manage configuration profiles.

lxc profile list [filters]                     List available profiles.
lxc profile show <profile>                     Show details of a profile.
lxc profile create <profile>                   Create a profile.
lxc profile copy <profile> <remote>            Copy the profile to the specified remote.
lxc profile set <profile> <key> <value>        Set profile configuration.
lxc profile delete <profile>                   Delete a profile.
lxc profile edit <profile>                     
    Edit profile, either by launching external editor or reading STDIN.
    Example: lxc profile edit <profile> # launch editor
             cat profile.yml | lxc profile edit <profile> # read from profile.yml
lxc profile apply <container> <profiles>
    Apply a comma-separated list of profiles to a container, in order.
    All profiles passed in this call (and only those) will be applied
    to the specified container.
    Example: lxc profile apply foo default,bar # Apply default and bar
             lxc profile apply foo default # Only default is active
             lxc profile apply '' # no profiles are applied anymore
             lxc profile apply bar,default # Apply default second now

Devices:
lxc profile device list <profile>              List devices in the given profile.
lxc profile device show <profile>              Show full device details in the given profile.
lxc profile device remove <profile> <name>     Remove a device from a profile.
lxc profile device add <profile name> <device name> <device type> [key=value]...
    Add a profile device, such as a disk or a nic, to the containers
    using the specified profile.`)
}
Ejemplo n.º 12
0
func (c *imageCmd) usage() string {
	return i18n.G(
		`Manipulate container images.

lxc image import <tarball> [rootfs tarball|URL] [target] [--public] [--created-at=ISO-8601] [--expires-at=ISO-8601] [--fingerprint=FINGERPRINT] [prop=value]

lxc image copy [remote:]<image> <remote>: [--alias=ALIAS].. [--copy-aliases] [--public]
lxc image delete [remote:]<image>
lxc image export [remote:]<image>
lxc image info [remote:]<image>
lxc image list [remote:] [filter]
lxc image show [remote:]<image>
lxc image edit [remote:]<image>
    Edit image, either by launching external editor or reading STDIN.
    Example: lxc image edit <image> # launch editor
             cat image.yml | lxc image edit <image> # read from image.yml

Lists the images at specified remote, or local images.
Filters are not yet supported.

lxc image alias create <alias> <target>
lxc image alias delete <alias>
lxc image alias list [remote:]

Create, delete, list image aliases. Example:
lxc remote add store2 images.linuxcontainers.org
lxc image alias list store2:`)
}
Ejemplo n.º 13
0
func doProfileDelete(client *lxd.Client, p string) error {
	err := client.ProfileDelete(p)
	if err == nil {
		fmt.Printf(i18n.G("Profile %s deleted")+"\n", p)
	}
	return err
}
Ejemplo n.º 14
0
Archivo: client.go Proyecto: djibi2/lxd
func (c *Client) ImageFromContainer(cname string, public bool, aliases []string, properties map[string]string) (string, error) {
	source := shared.Jmap{"type": "container", "name": cname}
	if shared.IsSnapshot(cname) {
		source["type"] = "snapshot"
	}
	body := shared.Jmap{"public": public, "source": source, "properties": properties}

	resp, err := c.post("images", body, Async)
	if err != nil {
		return "", err
	}

	jmap, err := c.AsyncWaitMeta(resp)
	if err != nil {
		return "", err
	}

	fingerprint, err := jmap.GetString("fingerprint")
	if err != nil {
		return "", err
	}

	/* add new aliases */
	for _, alias := range aliases {
		c.DeleteAlias(alias)
		err = c.PostAlias(alias, alias, fingerprint)
		if err != nil {
			fmt.Printf(i18n.G("Error adding alias %s")+"\n", alias)
		}
	}

	return fingerprint, nil
}
Ejemplo n.º 15
0
Archivo: config.go Proyecto: HPCNow/lxd
func deviceAdd(config *lxd.Config, which string, args []string) error {
	if len(args) < 5 {
		return errArgs
	}
	remote, name := config.ParseRemoteAndContainer(args[2])

	client, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	devname := args[3]
	devtype := args[4]
	var props []string
	if len(args) > 5 {
		props = args[5:]
	} else {
		props = []string{}
	}

	var resp *lxd.Response
	if which == "profile" {
		resp, err = client.ProfileDeviceAdd(name, devname, devtype, props)
	} else {
		resp, err = client.ContainerDeviceAdd(name, devname, devtype, props)
	}
	if err != nil {
		return err
	}
	fmt.Printf(i18n.G("Device %s added to %s")+"\n", devname, name)
	if which == "profile" {
		return nil
	}
	return client.WaitForSuccess(resp.Operation)
}
Ejemplo n.º 16
0
Archivo: client.go Proyecto: djibi2/lxd
func (c *Client) baseGet(getUrl string) (*Response, error) {
	req, err := http.NewRequest("GET", getUrl, nil)
	if err != nil {
		return nil, err
	}

	req.Header.Set("User-Agent", shared.UserAgent)

	resp, err := c.Http.Do(req)
	if err != nil {
		return nil, err
	}

	if c.scert != nil && resp.TLS != nil {
		if !bytes.Equal(resp.TLS.PeerCertificates[0].Raw, c.scert.Raw) {
			pUrl, _ := url.Parse(getUrl)
			return nil, fmt.Errorf(i18n.G("Server certificate for host %s has changed. Add correct certificate or remove certificate in %s"), pUrl.Host, c.Config.ConfigPath("servercerts"))
		}
	}

	if c.scertDigestSet == false && resp.TLS != nil {
		c.scertWire = resp.TLS.PeerCertificates[0]
		c.scertIntermediates = x509.NewCertPool()
		for _, cert := range resp.TLS.PeerCertificates {
			c.scertIntermediates.AddCert(cert)
		}
		c.scertDigest = sha256.Sum256(resp.TLS.PeerCertificates[0].Raw)
		c.scertDigestSet = true
	}

	return HoistResponse(resp, Sync)
}
Ejemplo n.º 17
0
Archivo: config.go Proyecto: HPCNow/lxd
func deviceRm(config *lxd.Config, which string, args []string) error {
	if len(args) < 4 {
		return errArgs
	}
	remote, name := config.ParseRemoteAndContainer(args[2])

	client, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	devname := args[3]
	var resp *lxd.Response
	if which == "profile" {
		resp, err = client.ProfileDeviceDelete(name, devname)
	} else {
		resp, err = client.ContainerDeviceDelete(name, devname)
	}
	if err != nil {
		return err
	}
	fmt.Printf(i18n.G("Device %s removed from %s")+"\n", devname, name)
	if which == "profile" {
		return nil
	}
	return client.WaitForSuccess(resp.Operation)
}
Ejemplo n.º 18
0
func containerInfo(d *lxd.Client, name string, showLog bool) error {
	ct, err := d.ContainerStatus(name)
	if err != nil {
		return err
	}

	fmt.Printf(i18n.G("Name: %s")+"\n", ct.Name)
	fmt.Printf(i18n.G("Status: %s")+"\n", ct.Status.Status)
	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\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"+i18n.G("Log:")+"\n\n%s\n", string(stuff))
	}

	return nil
}
Ejemplo n.º 19
0
Archivo: info.go Proyecto: hex2a/lxd
func (c *infoCmd) usage() string {
	return i18n.G(
		`List information on containers.

This will support remotes and images as well, but only containers for now.

lxc info [<remote>:]container [--show-log]`)
}
Ejemplo n.º 20
0
Archivo: client.go Proyecto: djibi2/lxd
func (c *Client) PutProfile(name string, profile shared.ProfileConfig) error {
	if profile.Name != name {
		return fmt.Errorf(i18n.G("Cannot change profile name"))
	}
	body := shared.Jmap{"name": name, "config": profile.Config, "devices": profile.Devices}
	_, err := c.put(fmt.Sprintf("profiles/%s", name), body, Sync)
	return err
}
Ejemplo n.º 21
0
func (c *deleteCmd) usage() string {
	return i18n.G(
		`Delete containers or container snapshots.

lxc delete [remote:]<container>[/<snapshot>] [remote:][<container>[/<snapshot>]...]

Destroy containers or snapshots with any attached data (configuration, snapshots, ...).`)
}
Ejemplo n.º 22
0
Archivo: init.go Proyecto: HPCNow/lxd
func (f *configList) Set(value string) error {
	if value == "" {
		return fmt.Errorf(i18n.G("Invalid configuration key"))
	}

	items := strings.SplitN(value, "=", 2)
	if len(items) < 2 {
		return fmt.Errorf(i18n.G("Invalid configuration key"))
	}

	if configMap == nil {
		configMap = map[string]string{}
	}

	configMap[items[0]] = items[1]

	return nil
}
Ejemplo n.º 23
0
func (c *imageCmd) usage() string {
	return i18n.G(
		`Manipulate container images.

In LXD containers are created from images. Those images were themselves
either generated from an existing container or downloaded from an image
server.

When using remote images, LXD will automatically cache images for you
and remove them upon expiration.

The image unique identifier is the hash (sha-256) of its representation
as a compressed tarball (or for split images, the concatenation of the
metadata and rootfs tarballs).

Images can be referenced by their full hash, shortest unique partial
hash or alias name (if one is set).


lxc image import <tarball> [rootfs tarball|URL] [remote:] [--public] [--created-at=ISO-8601] [--expires-at=ISO-8601] [--fingerprint=FINGERPRINT] [prop=value]
    Import an image tarball (or tarballs) into the LXD image store.

lxc image copy [remote:]<image> <remote>: [--alias=ALIAS].. [--copy-aliases] [--public]
    Copy an image from one LXD daemon to another over the network.

lxc image delete [remote:]<image>
    Delete an image from the LXD image store.

lxc image export [remote:]<image>
    Export an image from the LXD image store into a distributable tarball.

lxc image info [remote:]<image>
    Print everything LXD knows about a given image.

lxc image list [remote:] [filter]
    List images in the LXD image store. Filters may be of the
    <key>=<value> form for property based filtering, or part of the image
    hash or part of the image alias name.

lxc image show [remote:]<image>
    Yaml output of the user modifiable properties of an image.

lxc image edit [remote:]<image>
    Edit image, either by launching external editor or reading STDIN.
    Example: lxc image edit <image> # launch editor
             cat image.yml | lxc image edit <image> # read from image.yml

lxc image alias create [remote:]<alias> <fingerprint>
    Create a new alias for an existing image.

lxc image alias delete [remote:]<alias>
    Delete an alias.

lxc image alias list [remote:]
    List the aliases.
`)
}
Ejemplo n.º 24
0
func showAliases(aliases []shared.ImageAlias) error {
	data := [][]string{}
	for _, alias := range aliases {
		data = append(data, []string{alias.Description, alias.Name[0:12]})
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{
		i18n.G("ALIAS"),
		i18n.G("FINGERPRINT")})

	for _, v := range data {
		table.Append(v)
	}
	table.Render()

	return nil
}
Ejemplo n.º 25
0
Archivo: delete.go Proyecto: hex2a/lxd
func (c *deleteCmd) doDelete(d *lxd.Client, name string) error {
	if c.interactive {
		reader := bufio.NewReader(os.Stdin)
		fmt.Printf(i18n.G("Remove %s (yes/no): "), name)
		input, _ := reader.ReadString('\n')
		input = strings.TrimSuffix(input, "\n")
		if !shared.StringInSlice(strings.ToLower(input), []string{i18n.G("yes")}) {
			return fmt.Errorf(i18n.G("User aborted delete operation."))
		}
	}

	resp, err := d.Delete(name)
	if err != nil {
		return err
	}

	return d.WaitForSuccess(resp.Operation)
}
Ejemplo n.º 26
0
func (c *fileCmd) usage() string {
	return i18n.G(
		`Manage files on a container.

lxc file pull <source> [<source>...] <target>
lxc file push [--uid=UID] [--gid=GID] [--mode=MODE] <source> [<source>...] <target>
lxc file edit <file>

<source> in the case of pull, <target> in the case of push and <file> in the case of edit are <container name>/<path>`)
}
Ejemplo n.º 27
0
func showImages(images []shared.ImageInfo, filters []string) error {
	data := [][]string{}
	for _, image := range images {
		if !imageShouldShow(filters, &image) {
			continue
		}

		shortest := shortestAlias(image.Aliases)
		if len(image.Aliases) > 1 {
			shortest = fmt.Sprintf(i18n.G("%s (%d more)"), shortest, len(image.Aliases)-1)
		}
		fp := image.Fingerprint[0:12]
		public := i18n.G("no")
		description := findDescription(image.Properties)

		// FIXME: InterfaceToBool is there for backward compatibility
		if shared.InterfaceToBool(image.Public) {
			public = i18n.G("yes")
		}

		const layout = "Jan 2, 2006 at 3:04pm (MST)"
		uploaded := time.Unix(image.UploadDate, 0).Format(layout)
		arch, _ := shared.ArchitectureName(image.Architecture)
		size := fmt.Sprintf("%.2fMB", float64(image.Size)/1024.0/1024.0)
		data = append(data, []string{shortest, fp, public, description, arch, size, uploaded})
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetColWidth(50)
	table.SetHeader([]string{
		i18n.G("ALIAS"),
		i18n.G("FINGERPRINT"),
		i18n.G("PUBLIC"),
		i18n.G("DESCRIPTION"),
		i18n.G("ARCH"),
		i18n.G("SIZE"),
		i18n.G("UPLOAD DATE")})
	sort.Sort(ByName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}
Ejemplo n.º 28
0
// summaryLine returns the first line of the help text. Conventionally, this
// should be a one-line command summary, potentially followed by a longer
// explanation.
func summaryLine(usage string) string {
	usage = strings.TrimSpace(usage)
	s := bufio.NewScanner(bytes.NewBufferString(usage))
	if s.Scan() {
		if len(s.Text()) > 1 {
			return s.Text()
		}
	}
	return i18n.G("Missing summary.")
}
Ejemplo n.º 29
0
func (c *fileCmd) usage() string {
	return i18n.G(
		`Manage files on a container.

lxc file pull <source> [<source>...] <target>
lxc file push [--uid=UID] [--gid=GID] [--mode=MODE] <source> [<source>...] <target>
lxc file edit <file>

<source> in the case of pull, <target> in the case of push and <file> in the case of edit are <container name>/<path>
This operation is only supported on containers that are currently running`)
}
Ejemplo n.º 30
0
Archivo: move.go Proyecto: imoapps/lxd
func (c *moveCmd) usage() string {
	return i18n.G(
		`Move containers within or in between lxd instances.

lxc move [remote:]<source container> [remote:]<destination container>
    Move a container between two hosts, renaming it if destination name differs.

lxc move <old name> <new name>
    Rename a local container.
`)
}