示例#1
0
文件: config.go 项目: rrva/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(gettext.Gettext("Device %s added to %s\n"), devname, name)
	if which == "profile" {
		return nil
	}
	return client.WaitForSuccess(resp.Operation)
}
示例#2
0
文件: move.go 项目: imoapps/lxd
func (c *moveCmd) run(config *lxd.Config, args []string) error {
	if len(args) != 2 {
		return errArgs
	}

	sourceRemote, sourceName := config.ParseRemoteAndContainer(args[0])
	destRemote, destName := config.ParseRemoteAndContainer(args[1])

	// As an optimization, if the source an destination are the same, do
	// this via a simple rename. This only works for containers that aren't
	// running, containers that are running should be live migrated (of
	// course, this changing of hostname isn't supported right now, so this
	// simply won't work).
	if sourceRemote == destRemote {
		source, err := lxd.NewClient(config, sourceRemote)
		if err != nil {
			return err
		}

		rename, err := source.Rename(sourceName, destName)
		if err != nil {
			return err
		}

		return source.WaitForSuccess(rename.Operation)
	}

	// A move is just a copy followed by a delete; however, we want to
	// keep the volatile entries around since we are moving the container.
	if err := copyContainer(config, args[0], args[1], true, -1); err != nil {
		return err
	}

	return commands["delete"].run(config, args[:1])
}
示例#3
0
文件: config.go 项目: HPCNow/lxd
func doSet(config *lxd.Config, args []string) error {
	if len(args) != 4 {
		return errArgs
	}

	// [[lxc config]] set dakara:c1 limits.memory 200000
	remote, container := config.ParseRemoteAndContainer(args[1])
	d, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	key := args[2]
	value := args[3]

	if !terminal.IsTerminal(int(syscall.Stdin)) && value == "-" {
		buf, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			return fmt.Errorf("Can't read from stdin: %s", err)
		}
		value = string(buf[:])
	}

	return d.SetContainerConfig(container, key, value)
}
示例#4
0
文件: config.go 项目: rrva/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(gettext.Gettext("Device %s removed from %s\n"), devname, name)
	if which == "profile" {
		return nil
	}
	return client.WaitForSuccess(resp.Operation)
}
示例#5
0
文件: action.go 项目: rockstar/lxd
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(gettext.Gettext("bad result type from action"))
		}

		if err := d.WaitForSuccess(resp.Operation); err != nil {
			return fmt.Errorf("%s\n"+gettext.Gettext("Try `lxc info --show-log %s` for more info"), err, name)
		}
	}
	return nil
}
示例#6
0
文件: monitor.go 项目: ralic/lxd
func (c *monitorCmd) run(config *lxd.Config, args []string) error {
	var remote string

	if len(args) > 1 {
		return errArgs
	}

	if len(args) == 0 {
		remote, _ = config.ParseRemoteAndContainer("")
	} else {
		remote, _ = config.ParseRemoteAndContainer(args[0])
	}

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

	handler := func(message interface{}) {
		render, err := yaml.Marshal(&message)
		if err != nil {
			return
		}

		fmt.Printf("%s\n\n", render)
	}

	return d.Monitor(typeArgs, handler)
}
示例#7
0
文件: snapshot.go 项目: rrva/lxd
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(gettext.Gettext("'/' not allowed in snapshot name\n"))
	}

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

	return d.WaitForSuccess(resp.Operation)
}
示例#8
0
文件: delete.go 项目: akshaykarle/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 c.interactive {
			err := c.promptDelete(name)
			if err != nil {
				return err
			}
		}

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

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

		if ct.StatusCode != 0 && ct.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, false)
			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
}
示例#9
0
文件: exec.go 项目: argami/goard
func (c *execCmd) run(config *lxd.Config, args []string) error {
	if len(args) < 2 {
		return errArgs
	}

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

	env := map[string]string{"HOME": "/root", "USER": "******"}
	myEnv := os.Environ()
	for _, ent := range myEnv {
		if strings.HasPrefix(ent, "TERM=") {
			env["TERM"] = ent[len("TERM="):]
		}
	}

	for _, arg := range envArgs {
		pieces := strings.SplitN(arg, "=", 2)
		value := ""
		if len(pieces) > 1 {
			value = pieces[1]
		}
		env[pieces[0]] = value
	}

	cfd := syscall.Stdout
	var oldttystate *terminal.State
	if terminal.IsTerminal(cfd) {
		oldttystate, err = terminal.MakeRaw(cfd)
		if err != nil {
			return err
		}
		defer terminal.Restore(cfd, oldttystate)
	}

	ret, err := d.Exec(name, args[1:], env, os.Stdin, os.Stdout, os.Stderr)
	if err != nil {
		return err
	}

	if oldttystate != nil {
		/* A bit of a special case here: we want to exit with the same code as
		 * the process inside the container, so we explicitly exit here
		 * instead of returning an error.
		 *
		 * Additionally, since os.Exit() exits without running deferred
		 * functions, we restore the terminal explicitly.
		 */
		terminal.Restore(cfd, oldttystate)
	}

	/* we get the result of waitpid() here so we need to transform it */
	os.Exit(ret >> 8)
	return fmt.Errorf(gettext.Gettext("unreachable return reached"))
}
示例#10
0
文件: config.go 项目: vahe/lxd
func (c *configCmd) deviceSet(config *lxd.Config, which string, args []string) error {
	if len(args) < 6 {
		return errArgs
	}

	remote, name := config.ParseRemoteAndContainer(args[2])

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

	devname := args[3]
	key := args[4]
	value := args[5]

	if which == "profile" {
		st, err := client.ProfileConfig(name)
		if err != nil {
			return err
		}

		dev, ok := st.Devices[devname]
		if !ok {
			return fmt.Errorf(i18n.G("The device doesn't exist"))
		}

		dev[key] = value
		st.Devices[devname] = dev

		err = client.PutProfile(name, *st)
		if err != nil {
			return err
		}
	} else {
		st, err := client.ContainerInfo(name)
		if err != nil {
			return err
		}

		dev, ok := st.Devices[devname]
		if !ok {
			return fmt.Errorf(i18n.G("The device doesn't exist"))
		}

		dev[key] = value
		st.Devices[devname] = dev

		err = client.UpdateContainerConfig(name, st.Brief())
		if err != nil {
			return err
		}
	}

	return err
}
示例#11
0
文件: action.go 项目: jameinel/lxd
func (c *actionCmd) run(config *lxd.Config, args []string) error {
	if len(args) == 0 {
		return errArgs
	}

	state := false

	// Only store state if asked to
	if c.action == "stop" && c.stateful {
		state = true
	}

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

		if name == "" {
			return fmt.Errorf(i18n.G("Must supply container name for: ")+"\"%s\"", nameArg)
		}

		if c.action == shared.Start || c.action == shared.Stop {
			current, err := d.ContainerInfo(name)
			if err != nil {
				return err
			}

			// "start" for a frozen container means "unfreeze"
			if current.StatusCode == shared.Frozen {
				c.action = shared.Unfreeze
			}

			// Always restore state (if present) unless asked not to
			if c.action == shared.Start && current.Stateful && !c.stateless {
				state = true
			}
		}

		resp, err := d.Action(name, c.action, c.timeout, c.force, state)
		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
}
示例#12
0
文件: publish.go 项目: RuneTM/lxd
func (c *publishCmd) run(config *lxd.Config, args []string) error {
	var cRemote string
	var cName string
	iName := ""
	iRemote := ""
	properties := map[string]string{}
	firstprop := 1 // first property is arg[2] if arg[1] is image remote, else arg[1]

	if len(args) < 1 {
		return errArgs
	}

	cRemote, cName = config.ParseRemoteAndContainer(args[0])
	if len(args) >= 2 && !strings.Contains(args[1], "=") {
		firstprop = 2
		iRemote, iName = config.ParseRemoteAndContainer(args[1])
	}

	if cName == "" {
		return fmt.Errorf(gettext.Gettext("Container name is mandatory"))
	}
	if iName != "" {
		return fmt.Errorf(gettext.Gettext("There is no \"image name\".  Did you want an alias?"))
	}

	if cRemote != iRemote {
		/*
		 * Get the source remote to export the container over a websocket,
		 * pass that ws to the dest remote, and have it import it as an
		 * image
		 */
		return fmt.Errorf(gettext.Gettext("Publish to remote server is not supported yet"))
	}

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

	for i := firstprop; i < len(args); i++ {
		entry := strings.SplitN(args[i], "=", 2)
		if len(entry) < 2 {
			return errArgs
		}
		properties[entry[0]] = entry[1]
	}

	fp, err := d.ImageFromContainer(cName, makePublic, pAliases, properties)

	if err == nil {
		fmt.Printf("Container published with fingerprint %s\n", fp)
	}
	return err
}
示例#13
0
文件: profile.go 项目: achanda/lxd
func (c *profileCmd) run(config *lxd.Config, args []string) error {
	if len(args) < 1 {
		return errArgs
	}

	if args[0] == "list" {
		return doProfileList(config, args)
	}

	if len(args) < 2 {
		return errArgs
	}

	remote, profile := config.ParseRemoteAndContainer(args[1])
	client, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	switch args[0] {
	case "create":
		return doProfileCreate(client, profile)
	case "delete":
		return doProfileDelete(client, profile)
	case "device":
		return doProfileDevice(config, args)
	case "edit":
		return doProfileEdit(client, profile)
	case "apply":
		container := profile
		switch len(args) {
		case 2:
			profile = ""
		case 3:
			profile = args[2]
		default:
			return errArgs
		}
		return doProfileApply(client, container, profile)
	case "get":
		return doProfileGet(client, profile, args[2:])
	case "set":
		return doProfileSet(client, profile, args[2:])
	case "unset":
		return doProfileSet(client, profile, args[2:])
	case "copy":
		return doProfileCopy(config, client, profile, args[2:])
	case "show":
		return doProfileShow(client, profile)
	default:
		return fmt.Errorf(gettext.Gettext("unknown profile cmd %s"), args[0])
	}
}
示例#14
0
文件: network.go 项目: vahe/lxd
func (c *networkCmd) doNetworkList(config *lxd.Config, args []string) error {
	var remote string
	if len(args) > 1 {
		var name string
		remote, name = config.ParseRemoteAndContainer(args[1])
		if name != "" {
			return fmt.Errorf(i18n.G("Cannot provide container name to list"))
		}
	} else {
		remote = config.DefaultRemote
	}

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

	networks, err := client.ListNetworks()
	if err != nil {
		return err
	}

	data := [][]string{}
	for _, network := range networks {
		if shared.StringInSlice(network.Type, []string{"loopback", "unknown"}) {
			continue
		}

		strManaged := i18n.G("NO")
		if network.Managed {
			strManaged = i18n.G("YES")
		}

		strUsedBy := fmt.Sprintf("%d", len(network.UsedBy))
		data = append(data, []string{network.Name, network.Type, strManaged, strUsedBy})
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)
	table.SetHeader([]string{
		i18n.G("NAME"),
		i18n.G("TYPE"),
		i18n.G("MANAGED"),
		i18n.G("USED BY")})
	sort.Sort(byName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}
示例#15
0
文件: remote.go 项目: vahe/lxd
func generateClientCertificate(config *lxd.Config) error {
	// Generate a client certificate if necessary.  The default repositories are
	// either local or public, neither of which requires a client certificate.
	// Generation of the cert is delayed to avoid unnecessary overhead, e.g in
	// testing scenarios where only the default repositories are used.
	certf := config.ConfigPath("client.crt")
	keyf := config.ConfigPath("client.key")
	if !shared.PathExists(certf) || !shared.PathExists(keyf) {
		fmt.Fprintf(os.Stderr, i18n.G("Generating a client certificate. This may take a minute...")+"\n")

		return shared.FindOrGenCert(certf, keyf, true)
	}
	return nil
}
示例#16
0
文件: list.go 项目: vahe/lxd
func (c *listCmd) run(config *lxd.Config, args []string) error {
	var remote string
	name := ""

	filters := []string{}

	if len(args) != 0 {
		filters = args
		if strings.Contains(args[0], ":") && !strings.Contains(args[0], "=") {
			remote, name = config.ParseRemoteAndContainer(args[0])
			filters = args[1:]
		} else if !strings.Contains(args[0], "=") {
			remote = config.DefaultRemote
			name = args[0]
		}
	}
	filters = append(filters, name)

	if remote == "" {
		remote = config.DefaultRemote
	}

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

	var cts []shared.ContainerInfo
	ctslist, err := d.ListContainers()
	if err != nil {
		return err
	}

	for _, cinfo := range ctslist {
		if !c.shouldShow(filters, &cinfo) {
			continue
		}

		cts = append(cts, cinfo)
	}

	columns, err := c.parseColumns()
	if err != nil {
		return err
	}

	return c.listContainers(d, cts, filters, columns)
}
示例#17
0
文件: profile.go 项目: achanda/lxd
func doProfileCopy(config *lxd.Config, client *lxd.Client, p string, args []string) error {
	if len(args) != 1 {
		return errArgs
	}
	remote, newname := config.ParseRemoteAndContainer(args[0])
	if newname == "" {
		newname = p
	}

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

	return client.ProfileCopy(p, newname, dest)
}
示例#18
0
文件: finger.go 项目: Ramzec/lxd
func (c *fingerCmd) run(config *lxd.Config, args []string) error {
	if len(args) > 1 {
		return errArgs
	}

	var remote string
	if len(args) == 1 {
		remote = config.ParseRemote(args[0])
	} else {
		remote = config.DefaultRemote
	}

	// NewClient will finger the server to test the connection before returning.
	_, err := lxd.NewClient(config, remote)
	return err
}
示例#19
0
文件: config.go 项目: rrva/lxd
func doSet(config *lxd.Config, args []string) error {
	if len(args) != 4 {
		return errArgs
	}

	// [[lxc config]] set dakara:c1 limits.memory 200000
	remote, container := config.ParseRemoteAndContainer(args[1])
	d, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	key := args[2]
	value := args[3]
	return d.SetContainerConfig(container, key, value)
}
示例#20
0
文件: network.go 项目: vahe/lxd
func (c *networkCmd) run(config *lxd.Config, args []string) error {
	if len(args) < 1 {
		return errArgs
	}

	if args[0] == "list" {
		return c.doNetworkList(config, args)
	}

	if len(args) < 2 {
		return errArgs
	}

	remote, network := config.ParseRemoteAndContainer(args[1])
	client, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	switch args[0] {
	case "attach":
		return c.doNetworkAttach(client, network, args[2:])
	case "attach-profile":
		return c.doNetworkAttachProfile(client, network, args[2:])
	case "create":
		return c.doNetworkCreate(client, network, args[2:])
	case "delete":
		return c.doNetworkDelete(client, network)
	case "detach":
		return c.doNetworkDetach(client, network, args[2:])
	case "detach-profile":
		return c.doNetworkDetachProfile(client, network, args[2:])
	case "edit":
		return c.doNetworkEdit(client, network)
	case "get":
		return c.doNetworkGet(client, network, args[2:])
	case "set":
		return c.doNetworkSet(client, network, args[2:])
	case "unset":
		return c.doNetworkSet(client, network, args[2:])
	case "show":
		return c.doNetworkShow(client, network)
	default:
		return errArgs
	}
}
示例#21
0
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
		}

		ct, err := d.ContainerStatus(name)

		if err != nil {
			// Could be a snapshot
			return doDelete(d, name)
		}

		if ct.Status.StatusCode != shared.Stopped {
			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(gettext.Gettext("Stopping container failed!"))
			}

			if ct.Ephemeral == true {
				return nil
			}
		}
		if err := doDelete(d, name); err != nil {
			return err
		}
	}
	return nil

}
示例#22
0
文件: init.go 项目: kostyll/lxd
func (c *initCmd) run(config *lxd.Config, args []string) error {
	if len(args) > 2 || len(args) < 1 {
		return errArgs
	}

	iremote, image := config.ParseRemoteAndContainer(args[0])

	var name string
	var remote string
	if len(args) == 2 {
		remote, name = config.ParseRemoteAndContainer(args[1])
	} else {
		name = ""
		remote = ""
	}

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

	// TODO: implement the syntax for supporting other image types/remotes

	/*
	 * requested_empty_profiles means user requested empty
	 * !requested_empty_profiles but len(profArgs) == 0 means use profile default
	 */
	profiles := []string{}
	for _, p := range profArgs {
		profiles = append(profiles, p)
	}

	var resp *lxd.Response

	if !requested_empty_profiles && len(profiles) == 0 {
		resp, err = d.Init(name, iremote, image, nil, ephem)
	} else {
		resp, err = d.Init(name, iremote, image, &profiles, ephem)
	}

	if err != nil {
		return err
	}

	return d.WaitForSuccess(resp.Operation)
}
示例#23
0
文件: list.go 项目: xnox/lxd
func (c *listCmd) run(config *lxd.Config, args []string) error {
	var remote string
	name := ""

	filters := []string{}

	if len(args) != 0 {
		filters = args
		if strings.Contains(args[0], ":") {
			remote, name = config.ParseRemoteAndContainer(args[0])
			filters = args[1:]
		} else if !strings.Contains(args[0], "=") {
			remote = config.DefaultRemote
			name = args[0]
		}
	}

	if remote == "" {
		remote = config.DefaultRemote
	}

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

	var cts []shared.ContainerInfo
	ctslist, err := d.ListContainers()
	if err != nil {
		return err
	}

	if name == "" {
		cts = ctslist
	} else {
		for _, cinfo := range ctslist {
			if len(cinfo.State.Name) >= len(name) && cinfo.State.Name[0:len(name)] == name {
				cts = append(cts, cinfo)
			}
		}
	}

	return listContainers(cts, filters, len(cts) == 1)
}
示例#24
0
文件: config.go 项目: vahe/lxd
func (c *configCmd) deviceGet(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]
	key := args[4]

	if which == "profile" {
		st, err := client.ProfileConfig(name)
		if err != nil {
			return err
		}

		dev, ok := st.Devices[devname]
		if !ok {
			return fmt.Errorf(i18n.G("The device doesn't exist"))
		}

		fmt.Println(dev[key])
	} else {
		st, err := client.ContainerInfo(name)
		if err != nil {
			return err
		}

		dev, ok := st.Devices[devname]
		if !ok {
			return fmt.Errorf(i18n.G("The device doesn't exist"))
		}

		fmt.Println(dev[key])
	}

	return nil
}
示例#25
0
文件: image.go 项目: achanda/lxd
func doImageAlias(config *lxd.Config, args []string) error {
	var remote string
	switch args[1] {
	case "list":
		/* alias list [<remote>:] */
		if len(args) > 2 {
			remote, _ = config.ParseRemoteAndContainer(args[2])
		} else {
			remote, _ = config.ParseRemoteAndContainer("")
		}
		d, err := lxd.NewClient(config, remote)
		if err != nil {
			return err
		}

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

		showAliases(resp)

		return nil
	case "create":
		/* alias create [<remote>:]<alias> <target> */
		if len(args) < 4 {
			return errArgs
		}
		remote, alias := config.ParseRemoteAndContainer(args[2])
		target := args[3]
		d, err := lxd.NewClient(config, remote)
		if err != nil {
			return err
		}
		/* TODO - what about description? */
		err = d.PostAlias(alias, alias, target)
		return err
	case "delete":
		/* alias delete [<remote>:]<alias> */
		if len(args) < 3 {
			return errArgs
		}
		remote, alias := config.ParseRemoteAndContainer(args[2])
		d, err := lxd.NewClient(config, remote)
		if err != nil {
			return err
		}
		err = d.DeleteAlias(alias)
		return err
	}
	return errArgs
}
示例#26
0
文件: info.go 项目: ralic/lxd
func (c *infoCmd) run(config *lxd.Config, args []string) error {
	var remote string
	var cName string
	if len(args) == 1 {
		remote, cName = config.ParseRemoteAndContainer(args[0])
	} else {
		remote, cName = config.ParseRemoteAndContainer("")
	}

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

	if cName == "" {
		return remoteInfo(d)
	} else {
		return containerInfo(d, cName, c.showLog)
	}
}
示例#27
0
文件: profile.go 项目: vahe/lxd
func (c *profileCmd) doProfileList(config *lxd.Config, args []string) error {
	var remote string
	if len(args) > 1 {
		var name string
		remote, name = config.ParseRemoteAndContainer(args[1])
		if name != "" {
			return fmt.Errorf(i18n.G("Cannot provide container name to list"))
		}
	} else {
		remote = config.DefaultRemote
	}

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

	profiles, err := client.ListProfiles()
	if err != nil {
		return err
	}

	data := [][]string{}
	for _, profile := range profiles {
		strUsedBy := fmt.Sprintf("%d", len(profile.UsedBy))
		data = append(data, []string{profile.Name, strUsedBy})
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)
	table.SetHeader([]string{
		i18n.G("NAME"),
		i18n.G("USED BY")})
	sort.Sort(byName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}
示例#28
0
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
	remote := d.Get("remote").(string)
	scheme := d.Get("scheme").(string)

	daemon_addr := ""
	switch scheme {
	case "unix":
		daemon_addr = fmt.Sprintf("unix:%s", d.Get("address"))
	case "https":
		daemon_addr = fmt.Sprintf("https://%s:%s", d.Get("address"), d.Get("port"))
	default:
		err := fmt.Errorf("Invalid scheme: %s", scheme)
		return nil, err
	}

	// build LXD config
	config := lxd.Config{
		ConfigDir: os.ExpandEnv("$HOME/.config/lxc"),
		Remotes:   make(map[string]lxd.RemoteConfig),
	}
	config.Remotes[remote] = lxd.RemoteConfig{Addr: daemon_addr}
	log.Printf("[DEBUG] LXD Config: %#v", config)

	if scheme == "https" {
		// validate certifictes exist
		certf := config.ConfigPath("client.crt")
		keyf := config.ConfigPath("client.key")
		if !shared.PathExists(certf) || !shared.PathExists(keyf) {
			err := fmt.Errorf("Certificate or key not found:\n\t%s\n\t%s", certf, keyf)
			return nil, err
		}
		serverCertf := config.ServerCertPath(remote)
		if !shared.PathExists(serverCertf) {
			err := fmt.Errorf("Server certificate not found:\n\t%s", serverCertf)
			return nil, err
		}
	}

	client, err := lxd.NewClient(&config, remote)
	if err != nil {
		err := fmt.Errorf("Could not create LXD client: %s", err)
		return nil, err
	}
	log.Printf("[DEBUG] LXD Client: %#v", client)

	if err := validateClient(client); err != nil {
		return nil, err
	}

	lxdProv := LxdProvider{
		Remote: remote,
		Client: client,
	}

	return &lxdProv, nil
}
示例#29
0
文件: finger.go 项目: akshaykarle/lxd
func (c *fingerCmd) run(config *lxd.Config, args []string) error {
	if len(args) > 1 {
		return errArgs
	}

	var remote string
	if len(args) == 1 {
		remote = config.ParseRemote(args[0])
	} else {
		remote = config.DefaultRemote
	}

	// New client may or may not need to connect to the remote host, but
	// client.ServerStatus will at least request the basic information from
	// the server.
	client, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}
	_, err = client.ServerStatus()
	return err
}
示例#30
0
func checkFiles(c *gc.C, cfg lxdclient.Config) {
	var certificate lxdclient.Cert
	if cfg.Remote.Cert != nil {
		certificate = *cfg.Remote.Cert
	}

	filename := filepath.Join(cfg.Dirname, "client.crt")
	c.Logf("reading cert PEM from %q", filename)
	certPEM, err := ioutil.ReadFile(filename)
	c.Assert(err, jc.ErrorIsNil)
	c.Check(string(certPEM), gc.Equals, string(certificate.CertPEM))

	filename = filepath.Join(cfg.Dirname, "client.key")
	c.Logf("reading key PEM from %q", filename)
	keyPEM, err := ioutil.ReadFile(filename)
	c.Assert(err, jc.ErrorIsNil)
	c.Check(string(keyPEM), gc.Equals, string(certificate.KeyPEM))

	filename = filepath.Join(cfg.Dirname, "config.yml")
	c.Logf("reading config from %q", filename)
	configData, err := ioutil.ReadFile(filename)
	c.Assert(err, jc.ErrorIsNil)
	var config lxd.Config
	err = goyaml.Unmarshal(configData, &config)
	c.Assert(err, jc.ErrorIsNil)
	c.Check(config.Aliases, gc.HasLen, 0)
	config.Aliases = nil
	c.Check(config, jc.DeepEquals, lxd.Config{
		DefaultRemote: "local",
		Remotes: map[string]lxd.RemoteConfig{
			"local": lxd.LocalRemote,
			cfg.Remote.Name: lxd.RemoteConfig{
				Addr:   "https://" + cfg.Remote.Host + ":8443",
				Public: false,
			},
		},
		Aliases: nil,
	})
}