Skip to content

Commit

Permalink
Merge pull request #1691 from stgraber/master
Browse files Browse the repository at this point in the history
Remaining rc1 features
  • Loading branch information
tych0 committed Mar 2, 2016
2 parents 2982b64 + e4dfe43 commit 82d23a3
Show file tree
Hide file tree
Showing 25 changed files with 698 additions and 332 deletions.
11 changes: 3 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,13 @@ group to talk to LXD; you can create your own group if you want):

LXD has two parts, the daemon (the `lxd` binary), and the client (the `lxc`
binary). Now that the daemon is all configured and running (either via the
packaging or via the from-source instructions above), you can import an image:
packaging or via the from-source instructions above), you can create a container:

$GOPATH/src/github.com/lxc/lxd/scripts/lxd-images import ubuntu --alias ubuntu

With that image imported into LXD, you can now start containers:

$GOPATH/bin/lxc launch ubuntu
$GOPATH/bin/lxc launch ubuntu:14.04

Alternatively, you can also use a remote LXD host as a source of images.
Those will be automatically cached for you for up at container startup time:
One comes pre-configured in LXD, called "images" (images.linuxcontainers.org)

$GOPATH/bin/lxc remote add images images.linuxcontainers.org
$GOPATH/bin/lxc launch images:centos/7/amd64 centos

## Bug reports
Expand Down
63 changes: 24 additions & 39 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func (c *Client) baseGet(getUrl string) (*Response, error) {
return HoistResponse(resp, Sync)
}

func (c *Client) put(base string, args shared.Jmap, rtype ResponseType) (*Response, error) {
func (c *Client) put(base string, args interface{}, rtype ResponseType) (*Response, error) {
uri := c.url(shared.APIVersion, base)

buf := bytes.Buffer{}
Expand All @@ -396,7 +396,7 @@ func (c *Client) put(base string, args shared.Jmap, rtype ResponseType) (*Respon
return HoistResponse(resp, rtype)
}

func (c *Client) post(base string, args shared.Jmap, rtype ResponseType) (*Response, error) {
func (c *Client) post(base string, args interface{}, rtype ResponseType) (*Response, error) {
uri := c.url(shared.APIVersion, base)

buf := bytes.Buffer{}
Expand Down Expand Up @@ -446,7 +446,7 @@ func (c *Client) getRaw(uri string) (*http.Response, error) {
return raw, nil
}

func (c *Client) delete(base string, args shared.Jmap, rtype ResponseType) (*Response, error) {
func (c *Client) delete(base string, args interface{}, rtype ResponseType) (*Response, error) {
uri := c.url(shared.APIVersion, base)

buf := bytes.Buffer{}
Expand Down Expand Up @@ -565,7 +565,7 @@ func (c *Client) ListContainers() ([]shared.ContainerInfo, error) {
return result, nil
}

func (c *Client) CopyImage(image string, dest *Client, copy_aliases bool, aliases []string, public bool, progressHandler func(progress string)) error {
func (c *Client) CopyImage(image string, dest *Client, copy_aliases bool, aliases []string, public bool, autoUpdate bool, progressHandler func(progress string)) error {
source := shared.Jmap{
"type": "image",
"mode": "pull",
Expand Down Expand Up @@ -652,7 +652,7 @@ func (c *Client) CopyImage(image string, dest *Client, copy_aliases bool, aliase
sourceUrl := "https://" + addr

source["server"] = sourceUrl
body := shared.Jmap{"public": public, "source": source}
body := shared.Jmap{"public": public, "auto_update": autoUpdate, "source": source}

resp, err := dest.post("images", body, Async)
if err != nil {
Expand Down Expand Up @@ -1031,11 +1031,7 @@ func (c *Client) GetImageInfo(image string) (*shared.ImageInfo, error) {
}

func (c *Client) PutImageInfo(name string, p shared.BriefImageInfo) error {
body := shared.Jmap{}
body["public"] = p.Public
body["properties"] = p.Properties

_, err := c.put(fmt.Sprintf("images/%s", name), body, Sync)
_, err := c.put(fmt.Sprintf("images/%s", name), p, Sync)
return err
}

Expand Down Expand Up @@ -1173,7 +1169,7 @@ func (c *Client) Init(name string, imgremote string, image string, profiles *[]s
source := shared.Jmap{"type": "image"}

if image == "" {
return nil, fmt.Errorf("You must provide an image hash or alias name.")
image = "default"
}

if imgremote != c.Name {
Expand Down Expand Up @@ -1730,15 +1726,12 @@ func (c *Client) SetServerConfig(key string, value string) (*Response, error) {
}

ss.Config[key] = value
body := shared.Jmap{"config": ss.Config}

return c.put("", body, Sync)
return c.put("", ss, Sync)
}

func (c *Client) UpdateServerConfig(ss shared.BriefServerState) (*Response, error) {
body := shared.Jmap{"config": ss.Config}

return c.put("", body, Sync)
return c.put("", ss, Sync)
}

/*
Expand Down Expand Up @@ -1776,13 +1769,12 @@ func (c *Client) SetContainerConfig(container, key, value string) error {
st.Config[key] = value
}

body := shared.Jmap{"config": st.Config, "profiles": st.Profiles, "name": container, "devices": st.Devices}
/*
* Although container config is an async operation (we PUT to restore a
* snapshot), we expect config to be a sync operation, so let's just
* handle it here.
*/
resp, err := c.put(fmt.Sprintf("containers/%s", container), body, Async)
resp, err := c.put(fmt.Sprintf("containers/%s", container), st, Async)
if err != nil {
return err
}
Expand All @@ -1791,12 +1783,7 @@ func (c *Client) SetContainerConfig(container, key, value string) error {
}

func (c *Client) UpdateContainerConfig(container string, st shared.BriefContainerInfo) error {
body := shared.Jmap{"name": container,
"profiles": st.Profiles,
"config": st.Config,
"devices": st.Devices,
"ephemeral": st.Ephemeral}
resp, err := c.put(fmt.Sprintf("containers/%s", container), body, Async)
resp, err := c.put(fmt.Sprintf("containers/%s", container), st, Async)
if err != nil {
return err
}
Expand Down Expand Up @@ -1838,17 +1825,16 @@ func (c *Client) SetProfileConfigItem(profile, key, value string) error {
st.Config[key] = value
}

body := shared.Jmap{"name": profile, "config": st.Config, "devices": st.Devices}
_, err = c.put(fmt.Sprintf("profiles/%s", profile), body, Sync)
_, err = c.put(fmt.Sprintf("profiles/%s", profile), st, Sync)
return err
}

func (c *Client) PutProfile(name string, profile shared.ProfileConfig) error {
if profile.Name != name {
return fmt.Errorf("Cannot change profile name")
}
body := shared.Jmap{"name": name, "description": profile.Description, "config": profile.Config, "devices": profile.Devices}
_, err := c.put(fmt.Sprintf("profiles/%s", name), body, Sync)

_, err := c.put(fmt.Sprintf("profiles/%s", name), profile, Sync)
return err
}

Expand Down Expand Up @@ -1894,10 +1880,10 @@ func (c *Client) ApplyProfile(container, profile string) (*Response, error) {
if err != nil {
return nil, err
}
profiles := strings.Split(profile, ",")
body := shared.Jmap{"config": st.Config, "profiles": profiles, "name": st.Name, "devices": st.Devices}

return c.put(fmt.Sprintf("containers/%s", container), body, Async)
st.Profiles = strings.Split(profile, ",")

return c.put(fmt.Sprintf("containers/%s", container), st, Async)
}

func (c *Client) ContainerDeviceDelete(container, devname string) (*Response, error) {
Expand All @@ -1908,8 +1894,7 @@ func (c *Client) ContainerDeviceDelete(container, devname string) (*Response, er

delete(st.Devices, devname)

body := shared.Jmap{"config": st.Config, "profiles": st.Profiles, "name": st.Name, "devices": st.Devices}
return c.put(fmt.Sprintf("containers/%s", container), body, Async)
return c.put(fmt.Sprintf("containers/%s", container), st, Async)
}

func (c *Client) ContainerDeviceAdd(container, devname, devtype string, props []string) (*Response, error) {
Expand All @@ -1928,17 +1913,19 @@ func (c *Client) ContainerDeviceAdd(container, devname, devtype string, props []
v := results[1]
newdev[k] = v
}

if st.Devices != nil && st.Devices.ContainsName(devname) {
return nil, fmt.Errorf("device already exists")
}

newdev["type"] = devtype
if st.Devices == nil {
st.Devices = shared.Devices{}
}

st.Devices[devname] = newdev

body := shared.Jmap{"config": st.Config, "profiles": st.Profiles, "name": st.Name, "devices": st.Devices}
return c.put(fmt.Sprintf("containers/%s", container), body, Async)
return c.put(fmt.Sprintf("containers/%s", container), st, Async)
}

func (c *Client) ContainerListDevices(container string) ([]string, error) {
Expand All @@ -1965,8 +1952,7 @@ func (c *Client) ProfileDeviceDelete(profile, devname string) (*Response, error)
}
}

body := shared.Jmap{"config": st.Config, "name": st.Name, "devices": st.Devices}
return c.put(fmt.Sprintf("profiles/%s", profile), body, Sync)
return c.put(fmt.Sprintf("profiles/%s", profile), st, Sync)
}

func (c *Client) ProfileDeviceAdd(profile, devname, devtype string, props []string) (*Response, error) {
Expand Down Expand Up @@ -1994,8 +1980,7 @@ func (c *Client) ProfileDeviceAdd(profile, devname, devtype string, props []stri
}
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)
return c.put(fmt.Sprintf("profiles/%s", profile), st, Sync)
}

func (c *Client) ProfileListDevices(profile string) ([]string, error) {
Expand Down
1 change: 1 addition & 0 deletions lxc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ func (c *configCmd) run(config *lxd.Config, args []string) error {

table := tablewriter.NewWriter(os.Stdout)
table.SetAutoWrapText(false)
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetRowLine(true)
table.SetHeader([]string{
i18n.G("FINGERPRINT"),
Expand Down
Loading

0 comments on commit 82d23a3

Please sign in to comment.