Merge lp:~sidnei/golxc/clone-with-backing-store into lp:golxc
- clone-with-backing-store
- Merge into trunk
| Status: | Needs review |
|---|---|
| Proposed branch: | lp:~sidnei/golxc/clone-with-backing-store |
| Merge into: | lp:golxc |
| Diff against target: | 169 lines (+70/-10) 3 files modified golxc.go (+42/-6) golxc_test.go (+27/-3) network.go (+1/-1) |
| To merge this branch: | bzr merge lp:~sidnei/golxc/clone-with-backing-store |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Juju Engineering | Pending | ||
| Review via email: | |||
Commit message
Description of the change
Suport extra args for lxc-clone in lxc 1.0alpha2
Allow using snapshots for cloning, selecting a specific backing store and also
passing template arguments to whatever template was used when cloning.
| John A Meinel (jameinel) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 2013-10-23 2:29, Sidnei da Silva wrote:
> Sidnei da Silva has proposed merging
> lp:~sidnei/golxc/clone-with-backing-store into lp:golxc.
>
> Requested reviews: juju hackers (juju) Related bugs: Bug #1203291
> in juju-core: "local provider moar awesome with lxc-clone"
> https:/
>
> For more details, see:
> https:/
>
> Suport extra args for lxc-clone in lxc 0.9
>
> Allow using snapshots for cloning, selecting a specific backing
> store and also passing template arguments to whatever template was
> used when cloning.
>
Is this backwards compatible for the version of LXC that is default
installed in Precise?
Can it be made to be that way?
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (Cygwin)
Comment: Using GnuPG with Thunderbird - http://
iEYEARECAAYFAlJ
sz4AoNOATEPIfLt
=VrL9
-----END PGP SIGNATURE-----
| Sidnei da Silva (sidnei) wrote : | # |
On Tue, Nov 5, 2013 at 5:36 AM, John A Meinel <email address hidden>wrote:
>
> Is this backwards compatible for the version of LXC that is default
> installed in Precise?
>
> Can it be made to be that way?
>
It isn't because there's extra arguments that weren't there before. It
could be made compatible by sniffing out valid arguments from lxc-create
--help and lxc-clone --help, but I feel that could be too fragile. My
understanding is that lxc would be backported into the cloud archive all
the way to precise, but maybe that's not the case?
--
Sidnei
Make the most of Ubuntu with Ubuntu One
http://
Unmerged revisions
- 9. By Sidnei da Silva
-
- Don't conditionally set options
- 8. By Sidnei da Silva
-
- Expose more settings via create and clone
- 7. By Sidnei da Silva
-
- Some test tweaks
- 6. By Sidnei da Silva
-
- Initial attempt with simply modifying the interface in place, better advice to come.
Preview Diff
| 1 | === modified file 'golxc.go' |
| 2 | --- golxc.go 2013-06-14 01:27:52 +0000 |
| 3 | +++ golxc.go 2013-10-22 22:26:14 +0000 |
| 4 | @@ -57,6 +57,18 @@ |
| 5 | LogFatal LogLevel = "FATAL" |
| 6 | ) |
| 7 | |
| 8 | +// BackingStore represents a container's backing store when cloning. |
| 9 | +type BackingStore string |
| 10 | + |
| 11 | +const ( |
| 12 | + BackingStoreAuto BackingStore = "auto" |
| 13 | + BackingStoreLVM BackingStore = "lvm" |
| 14 | + BackingStoreBTRFS BackingStore = "btrfs" |
| 15 | + BackingStoreOverlayFS BackingStore = "overlayfs" |
| 16 | + BackingStoreDir BackingStore = "dir" |
| 17 | + BackingStoreLoop BackingStore = "loop" |
| 18 | +) |
| 19 | + |
| 20 | // Container represents a linux container instance and provides |
| 21 | // operations to create, maintain and destroy the container. |
| 22 | type Container interface { |
| 23 | @@ -65,16 +77,16 @@ |
| 24 | Name() string |
| 25 | |
| 26 | // Create creates a new container based on the given template. |
| 27 | - Create(configFile, template string, templateArgs ...string) error |
| 28 | + Create(configFile string, backingStore BackingStore, fsSize string, fsType string, template string, templateArgs ...string) error |
| 29 | |
| 30 | // Start runs the container as a daemon. |
| 31 | - Start(configFile, consoleFile string) error |
| 32 | + Start(configFile string, consoleFile string) error |
| 33 | |
| 34 | // Stop terminates the running container. |
| 35 | Stop() error |
| 36 | |
| 37 | // Clone creates a copy of the container, giving the copy the specified name. |
| 38 | - Clone(name string) (Container, error) |
| 39 | + Clone(name string, snapshot bool, backingStore BackingStore, fsSize string, templateArgs ...string) (Container, error) |
| 40 | |
| 41 | // Freeze freezes all the container's processes. |
| 42 | Freeze() error |
| 43 | @@ -179,7 +191,7 @@ |
| 44 | } |
| 45 | |
| 46 | // Create creates a new container based on the given template. |
| 47 | -func (c *container) Create(configFile, template string, templateArgs ...string) error { |
| 48 | +func (c *container) Create(configFile string, backingStore BackingStore, fsSize string, fsType string, template string, templateArgs ...string) error { |
| 49 | if c.IsConstructed() { |
| 50 | return fmt.Errorf("container %q is already created", c.Name()) |
| 51 | } |
| 52 | @@ -190,8 +202,19 @@ |
| 53 | if configFile != "" { |
| 54 | args = append(args, "-f", configFile) |
| 55 | } |
| 56 | - args = append(args, "--") |
| 57 | + if backingStore != BackingStoreAuto { |
| 58 | + args = append(args, "-B", string(backingStore)) |
| 59 | + } else { |
| 60 | + args = append(args, "-B", "best") |
| 61 | + } |
| 62 | + if fsSize != "" { |
| 63 | + args = append(args, "--fssize", fsSize) |
| 64 | + } |
| 65 | + if fsType != "" { |
| 66 | + args = append(args, "--fstype", fsType) |
| 67 | + } |
| 68 | if len(templateArgs) != 0 { |
| 69 | + args = append(args, "--") |
| 70 | args = append(args, templateArgs...) |
| 71 | } |
| 72 | _, err := run("lxc-create", args...) |
| 73 | @@ -245,7 +268,7 @@ |
| 74 | } |
| 75 | |
| 76 | // Clone creates a copy of the container, it gets the given name. |
| 77 | -func (c *container) Clone(name string) (Container, error) { |
| 78 | +func (c *container) Clone(name string, snapshot bool, backingStore BackingStore, fsSize string, templateArgs ...string) (Container, error) { |
| 79 | if !c.IsConstructed() { |
| 80 | return nil, fmt.Errorf("container %q is not yet created", c.name) |
| 81 | } |
| 82 | @@ -259,6 +282,19 @@ |
| 83 | "-o", c.name, |
| 84 | "-n", name, |
| 85 | } |
| 86 | + if snapshot { |
| 87 | + args = append(args, "-s") |
| 88 | + } |
| 89 | + if backingStore != BackingStoreAuto { |
| 90 | + args = append(args, "-B", string(backingStore)) |
| 91 | + } |
| 92 | + if fsSize != "" { |
| 93 | + args = append(args, "-L", fsSize) |
| 94 | + } |
| 95 | + if len(templateArgs) != 0 { |
| 96 | + args = append(args, "--") |
| 97 | + args = append(args, templateArgs...) |
| 98 | + } |
| 99 | _, err := run("lxc-clone", args...) |
| 100 | if err != nil { |
| 101 | return nil, err |
| 102 | |
| 103 | === modified file 'golxc_test.go' |
| 104 | --- golxc_test.go 2013-06-14 03:27:43 +0000 |
| 105 | +++ golxc_test.go 2013-10-22 22:26:14 +0000 |
| 106 | @@ -16,7 +16,7 @@ |
| 107 | var lxcfile = `# MIRROR to be used by ubuntu template at container creation: |
| 108 | # Leaving it undefined is fine |
| 109 | #MIRROR="http://archive.ubuntu.com/ubuntu" |
| 110 | -# or |
| 111 | +# or |
| 112 | #MIRROR="http://<host-ip-addr>:3142/archive.ubuntu.com/ubuntu" |
| 113 | |
| 114 | # LXC_AUTO - whether or not to start containers symlinked under |
| 115 | @@ -232,7 +232,31 @@ |
| 116 | }() |
| 117 | lcs, _ := s.factory.List() |
| 118 | oldLen := len(lcs) |
| 119 | - lc2, err := lc1.Clone("golxcclone") |
| 120 | + lc2, err := lc1.Clone("golxcclone", false, golxc.BackingStoreAuto) |
| 121 | + c.Assert(err, IsNil) |
| 122 | + c.Assert(lc2.IsConstructed(), Equals, true) |
| 123 | + defer func() { |
| 124 | + c.Assert(lc2.Destroy(), IsNil) |
| 125 | + }() |
| 126 | + lcs, _ = s.factory.List() |
| 127 | + newLen := len(lcs) |
| 128 | + c.Assert(newLen == oldLen+1, Equals, true) |
| 129 | + c.Assert(contains(lcs, lc1), Equals, true) |
| 130 | + c.Assert(contains(lcs, lc2), Equals, true) |
| 131 | +} |
| 132 | + |
| 133 | +func (s *LXCSuite) TestCloneSnapshotWithOverlayFS(c *C) { |
| 134 | + // Test the cloning of an existing container. |
| 135 | + lc1 := s.factory.New("golxc") |
| 136 | + c.Assert(lc1.IsConstructed(), Equals, false) |
| 137 | + c.Assert(lc1.Create("", "ubuntu"), IsNil) |
| 138 | + c.Assert(lc1.IsConstructed(), Equals, true) |
| 139 | + defer func() { |
| 140 | + c.Assert(lc1.Destroy(), IsNil) |
| 141 | + }() |
| 142 | + lcs, _ := s.factory.List() |
| 143 | + oldLen := len(lcs) |
| 144 | + lc2, err := lc1.Clone("golxcclone", true, golxc.BackingStoreOverlayFS) |
| 145 | c.Assert(err, IsNil) |
| 146 | c.Assert(lc2.IsConstructed(), Equals, true) |
| 147 | defer func() { |
| 148 | @@ -249,7 +273,7 @@ |
| 149 | // Test the cloning of a non-existing container. |
| 150 | lc := s.factory.New("golxc") |
| 151 | c.Assert(lc.IsConstructed(), Equals, false) |
| 152 | - _, err := lc.Clone("golxcclone") |
| 153 | + _, err := lc.Clone("golxcclone", false, golxc.BackingStoreAuto) |
| 154 | c.Assert(err, ErrorMatches, "container .* is not yet created") |
| 155 | } |
| 156 | |
| 157 | |
| 158 | === modified file 'network.go' |
| 159 | --- network.go 2013-06-14 00:29:08 +0000 |
| 160 | +++ network.go 2013-10-22 22:26:14 +0000 |
| 161 | @@ -53,7 +53,7 @@ |
| 162 | return status == "running", nil |
| 163 | } |
| 164 | |
| 165 | -// NetworkAttributes returns the lxc network attributes: |
| 166 | +// NetworkAttributes returns the lxc network attributes: |
| 167 | // starting IP address and bridge name. |
| 168 | func NetworkAttributes() (addr, bridge string, err error) { |
| 169 | config, err := ReadConf() |
Please take a look.