The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/distrobuilder/pull/277
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === This PR contains changes in preparation for VM support.
From 65112ce0b9a49cb33fbec289e38135ff9577be25 Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Wed, 12 Feb 2020 17:29:44 +0100 Subject: [PATCH 1/7] shared/definition: Add LXD target Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- shared/definition.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/shared/definition.go b/shared/definition.go index 7b586d5..62262a7 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -129,9 +129,21 @@ type DefinitionTargetLXC struct { Config []DefinitionTargetLXCConfig `yaml:"config,omitempty"` } +// DefinitionTargetLXDVM represents LXD VM specific options. +type DefinitionTargetLXDVM struct { + Size uint `yaml:"size,omitempty"` + Filesystem string `yaml:"filesystem,omitempty"` +} + +// DefinitionTargetLXD represents LXD specific options. +type DefinitionTargetLXD struct { + VM DefinitionTargetLXDVM `yaml:"vm,omitempty"` +} + // A DefinitionTarget specifies target dependent files. type DefinitionTarget struct { LXC DefinitionTargetLXC `yaml:"lxc,omitempty"` + LXD DefinitionTargetLXD `yaml:"lxd,omitempty"` } // A DefinitionFile represents a file which is to be created inside to chroot. From 39d263ae2a10b14070485c9dd6fdd66ab0282779 Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Wed, 12 Feb 2020 17:32:20 +0100 Subject: [PATCH 2/7] shared/definition: Add VM field to target This add a VM field to target which is for internal use only. It makes it simpler to deal with VMs as it removes the necessity of passing the value of the --vm flag. Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- shared/definition.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shared/definition.go b/shared/definition.go index 62262a7..ff0c30d 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -142,8 +142,9 @@ type DefinitionTargetLXD struct { // A DefinitionTarget specifies target dependent files. type DefinitionTarget struct { - LXC DefinitionTargetLXC `yaml:"lxc,omitempty"` - LXD DefinitionTargetLXD `yaml:"lxd,omitempty"` + LXC DefinitionTargetLXC `yaml:"lxc,omitempty"` + LXD DefinitionTargetLXD `yaml:"lxd,omitempty"` + Type string // This field is internal only and used only for simplicity. } // A DefinitionFile represents a file which is to be created inside to chroot. @@ -278,6 +279,9 @@ func (d *Definition) SetDefaults() { if d.Image.Description == "" { d.Image.Description = "{{ image.distribution|capfirst }} {{ image.release }} {{ image.architecture_mapped }}{% if image.variant != \"default\" %} ({{ image.variant }}){% endif %} ({{ image.serial }})" } + + // Set default target type. This will only be overriden if building VMs for LXD. + d.Targets.Type = "container" } // Validate validates the Definition. From e41a1a15767bead9333b30c78f2f8188892bf927 Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Wed, 12 Feb 2020 17:34:08 +0100 Subject: [PATCH 3/7] shared/definition: Add GetTypes to filter This adds a new `types` filter which is used for differentiating between containers and VMs. Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- shared/definition.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shared/definition.go b/shared/definition.go index ff0c30d..23a4006 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -17,6 +17,7 @@ type Filter interface { GetReleases() []string GetArchitectures() []string GetVariants() []string + GetTypes() []string } // A DefinitionFilter defines filters for various actions. @@ -24,6 +25,7 @@ type DefinitionFilter struct { Releases []string `yaml:"releases,omitempty"` Architectures []string `yaml:"architectures,omitempty"` Variants []string `yaml:"variants,omitempty"` + Types []string `yaml:"types,omitempty"` } // GetReleases returns a list of releases. @@ -41,6 +43,11 @@ func (d *DefinitionFilter) GetVariants() []string { return d.Variants } +// GetTypes returns a list of types. +func (d *DefinitionFilter) GetTypes() []string { + return d.Types +} + // A DefinitionPackagesSet is a set of packages which are to be installed // or removed. type DefinitionPackagesSet struct { From 907bf785d2a15b1094c7e9a145971de65924d7ae Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Tue, 29 Oct 2019 13:38:12 +0100 Subject: [PATCH 4/7] shared: Export ChrootMount struct This exports the ChrootMount struct. Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- shared/chroot.go | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/shared/chroot.go b/shared/chroot.go index eefdeab..a6ad591 100644 --- a/shared/chroot.go +++ b/shared/chroot.go @@ -12,19 +12,20 @@ import ( lxd "github.com/lxc/lxd/shared" ) -type chrootMount struct { - source string - target string - fstype string - flags uintptr - data string - isDir bool +// ChrootMount defines mount args. +type ChrootMount struct { + Source string + Target string + FSType string + Flags uintptr + Data string + IsDir bool } // ActiveChroots is a map of all active chroots and their exit functions var ActiveChroots = make(map[string]func() error) -func setupMounts(rootfs string, mounts []chrootMount) error { +func setupMounts(rootfs string, mounts []ChrootMount) error { // Create a temporary mount path err := os.MkdirAll(filepath.Join(rootfs, ".distrobuilder"), 0700) if err != nil { @@ -36,7 +37,7 @@ func setupMounts(rootfs string, mounts []chrootMount) error { tmpTarget := filepath.Join(rootfs, ".distrobuilder", fmt.Sprintf("%d", i)) // Create the target mountpoint - if mount.isDir { + if mount.IsDir { err := os.MkdirAll(tmpTarget, 0755) if err != nil { return err @@ -49,22 +50,22 @@ func setupMounts(rootfs string, mounts []chrootMount) error { } // Mount to the temporary path - err := syscall.Mount(mount.source, tmpTarget, mount.fstype, mount.flags, mount.data) + err := syscall.Mount(mount.Source, tmpTarget, mount.FSType, mount.Flags, mount.Data) if err != nil { - return fmt.Errorf("Failed to mount '%s': %s", mount.source, err) + return fmt.Errorf("Failed to mount '%s': %s", mount.Source, err) } } return nil } -func moveMounts(mounts []chrootMount) error { +func moveMounts(mounts []ChrootMount) error { for i, mount := range mounts { // Source path tmpSource := filepath.Join("/", ".distrobuilder", fmt.Sprintf("%d", i)) // Resolve symlinks - target := mount.target + target := mount.Target for { // Get information on current target fi, err := os.Lstat(target) @@ -93,7 +94,7 @@ func moveMounts(mounts []chrootMount) error { } // Create target path - if mount.isDir { + if mount.IsDir { err = os.MkdirAll(target, 0755) if err != nil { return err @@ -108,7 +109,7 @@ func moveMounts(mounts []chrootMount) error { // Move the mount to its destination err = syscall.Mount(tmpSource, target, "", syscall.MS_MOVE, "") if err != nil { - return fmt.Errorf("Failed to mount '%s': %s", mount.source, err) + return fmt.Errorf("Failed to mount '%s': %s", mount.Source, err) } } @@ -159,7 +160,7 @@ func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { } // Setup all other needed mounts - mounts := []chrootMount{ + mounts := []ChrootMount{ {"none", "/proc", "proc", 0, "", true}, {"none", "/sys", "sysfs", 0, "", true}, {"/dev", "/dev", "", syscall.MS_BIND, "", true}, From 2e5d184154a038f6d7ed252cac21b91a7de2f505 Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Tue, 29 Oct 2019 15:07:57 +0100 Subject: [PATCH 5/7] *: Pass custom mounts to SetupChroot() This allows additional mounts to be passed to SetupChroot() Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- distrobuilder/main.go | 2 +- distrobuilder/main_lxc.go | 2 +- distrobuilder/main_lxd.go | 2 +- shared/chroot.go | 10 +++++++--- sources/alpine-http.go | 2 +- sources/centos-http.go | 4 ++-- sources/oraclelinux-http.go | 2 +- sources/ubuntu-http.go | 2 +- 8 files changed, 15 insertions(+), 11 deletions(-) diff --git a/distrobuilder/main.go b/distrobuilder/main.go index 043d656..e820357 100644 --- a/distrobuilder/main.go +++ b/distrobuilder/main.go @@ -251,7 +251,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(c.sourceDir, c.definition.Environment) + exitChroot, err := shared.SetupChroot(c.sourceDir, c.definition.Environment, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } diff --git a/distrobuilder/main_lxc.go b/distrobuilder/main_lxc.go index 0b8fb77..9ce050e 100644 --- a/distrobuilder/main_lxc.go +++ b/distrobuilder/main_lxc.go @@ -60,7 +60,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { } exitChroot, err := shared.SetupChroot(c.global.sourceDir, - c.global.definition.Environment) + c.global.definition.Environment, nil) if err != nil { return err } diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go index 9aea6dc..73596bb 100644 --- a/distrobuilder/main_lxd.go +++ b/distrobuilder/main_lxd.go @@ -85,7 +85,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { } exitChroot, err := shared.SetupChroot(c.global.sourceDir, - c.global.definition.Environment) + c.global.definition.Environment, nil) if err != nil { return err } diff --git a/shared/chroot.go b/shared/chroot.go index a6ad591..1c652b3 100644 --- a/shared/chroot.go +++ b/shared/chroot.go @@ -152,7 +152,7 @@ func killChrootProcesses(rootfs string) error { } // SetupChroot sets up mount and files, a reverter and then chroots for you -func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { +func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() error, error) { // Mount the rootfs err := syscall.Mount(rootfs, rootfs, "", syscall.MS_BIND, "") if err != nil { @@ -181,7 +181,11 @@ func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { } // Setup all needed mounts in a temporary location - err = setupMounts(rootfs, mounts) + if m != nil && len(m) > 0 { + err = setupMounts(rootfs, append(mounts, m...)) + } else { + err = setupMounts(rootfs, mounts) + } if err != nil { return nil, fmt.Errorf("Failed to mount filesystems: %v", err) } @@ -199,7 +203,7 @@ func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { } // Move all the mounts into place - err = moveMounts(mounts) + err = moveMounts(append(mounts, m...)) if err != nil { return nil, err } diff --git a/sources/alpine-http.go b/sources/alpine-http.go index ecb95a6..4edd5d7 100644 --- a/sources/alpine-http.go +++ b/sources/alpine-http.go @@ -98,7 +98,7 @@ func (s *AlpineLinuxHTTP) Run(definition shared.Definition, rootfsDir string) er // Handle edge builds if definition.Image.Release == "edge" { // Upgrade to edge - exitChroot, err := shared.SetupChroot(rootfsDir, definition.Environment) + exitChroot, err := shared.SetupChroot(rootfsDir, definition.Environment, nil) if err != nil { return err } diff --git a/sources/centos-http.go b/sources/centos-http.go index d23bf1c..9888217 100644 --- a/sources/centos-http.go +++ b/sources/centos-http.go @@ -169,7 +169,7 @@ func (s CentOSHTTP) unpackRaw(filePath, rootfsDir string) error { } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } @@ -296,7 +296,7 @@ func (s CentOSHTTP) unpackISO(filePath, rootfsDir string) error { } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } diff --git a/sources/oraclelinux-http.go b/sources/oraclelinux-http.go index 4906455..6d21904 100644 --- a/sources/oraclelinux-http.go +++ b/sources/oraclelinux-http.go @@ -169,7 +169,7 @@ func (s *OracleLinuxHTTP) unpackISO(latestUpdate, filePath, rootfsDir string) er } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } diff --git a/sources/ubuntu-http.go b/sources/ubuntu-http.go index b82042a..c7ca68c 100644 --- a/sources/ubuntu-http.go +++ b/sources/ubuntu-http.go @@ -150,7 +150,7 @@ func (s *UbuntuHTTP) runCoreVariant(definition shared.Definition, rootfsDir stri return err } - exitChroot, err := shared.SetupChroot(baseImageDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(baseImageDir, shared.DefinitionEnv{}, nil) if err != nil { return err } From 7528172e2c76791abae1dfd958ce3b99b3b2e4df Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Wed, 12 Feb 2020 17:37:30 +0100 Subject: [PATCH 6/7] *: Support VM filtering Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- distrobuilder/chroot.go | 10 +++++----- distrobuilder/main.go | 8 ++++---- distrobuilder/main_build-dir.go | 2 +- distrobuilder/main_lxc.go | 4 ++-- distrobuilder/main_lxd.go | 4 ++-- shared/definition.go | 22 ++++++++++++++++++---- shared/definition_test.go | 26 ++++++++++++++++++++++++-- 7 files changed, 56 insertions(+), 20 deletions(-) diff --git a/distrobuilder/chroot.go b/distrobuilder/chroot.go index 0602469..a723d54 100644 --- a/distrobuilder/chroot.go +++ b/distrobuilder/chroot.go @@ -8,7 +8,7 @@ import ( "github.com/lxc/distrobuilder/shared" ) -func manageRepositories(def *shared.Definition, manager *managers.Manager) error { +func manageRepositories(def *shared.Definition, manager *managers.Manager, vmOnly bool) error { var err error if def.Packages.Repositories == nil || len(def.Packages.Repositories) == 0 { @@ -21,7 +21,7 @@ func manageRepositories(def *shared.Definition, manager *managers.Manager) error } for _, repo := range def.Packages.Repositories { - if !shared.ApplyFilter(&repo, def.Image.Release, def.Image.ArchitectureMapped, def.Image.Variant) { + if !shared.ApplyFilter(&repo, def.Image.Release, def.Image.ArchitectureMapped, def.Image.Variant, def.Targets.Type, vmOnly) { continue } @@ -46,7 +46,7 @@ func manageRepositories(def *shared.Definition, manager *managers.Manager) error return nil } -func managePackages(def *shared.Definition, manager *managers.Manager) error { +func managePackages(def *shared.Definition, manager *managers.Manager, vmOnly bool) error { var err error err = manager.Refresh() @@ -61,7 +61,7 @@ func managePackages(def *shared.Definition, manager *managers.Manager) error { } // Run post update hook - for _, action := range def.GetRunnableActions("post-update") { + for _, action := range def.GetRunnableActions("post-update", vmOnly) { err = shared.RunScript(action.Action) if err != nil { return fmt.Errorf("Failed to run post-update: %s", err) @@ -72,7 +72,7 @@ func managePackages(def *shared.Definition, manager *managers.Manager) error { var validSets []shared.DefinitionPackagesSet for _, set := range def.Packages.Sets { - if !shared.ApplyFilter(&set, def.Image.Release, def.Image.ArchitectureMapped, def.Image.Variant) { + if !shared.ApplyFilter(&set, def.Image.Release, def.Image.ArchitectureMapped, def.Image.Variant, def.Targets.Type, vmOnly) { continue } diff --git a/distrobuilder/main.go b/distrobuilder/main.go index e820357..a963e1e 100644 --- a/distrobuilder/main.go +++ b/distrobuilder/main.go @@ -269,13 +269,13 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { manager = managers.GetCustom(*c.definition.Packages.CustomManager) } - err = manageRepositories(c.definition, manager) + err = manageRepositories(c.definition, manager, false) if err != nil { return fmt.Errorf("Failed to manage repositories: %s", err) } // Run post unpack hook - for _, hook := range c.definition.GetRunnableActions("post-unpack") { + for _, hook := range c.definition.GetRunnableActions("post-unpack", false) { err := shared.RunScript(hook.Action) if err != nil { return fmt.Errorf("Failed to run post-unpack: %s", err) @@ -283,13 +283,13 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { } // Install/remove/update packages - err = managePackages(c.definition, manager) + err = managePackages(c.definition, manager, false) if err != nil { return fmt.Errorf("Failed to manage packages: %s", err) } // Run post packages hook - for _, hook := range c.definition.GetRunnableActions("post-packages") { + for _, hook := range c.definition.GetRunnableActions("post-packages", false) { err := shared.RunScript(hook.Action) if err != nil { return fmt.Errorf("Failed to run post-packages: %s", err) diff --git a/distrobuilder/main_build-dir.go b/distrobuilder/main_build-dir.go index 3f8a3a0..e7ab644 100644 --- a/distrobuilder/main_build-dir.go +++ b/distrobuilder/main_build-dir.go @@ -28,7 +28,7 @@ func (c *cmdBuildDir) command() *cobra.Command { return fmt.Errorf("Unknown generator '%s'", file.Generator) } - if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant) { + if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant, c.global.definition.Targets.Type, false) { continue } diff --git a/distrobuilder/main_lxc.go b/distrobuilder/main_lxc.go index 9ce050e..0990d32 100644 --- a/distrobuilder/main_lxc.go +++ b/distrobuilder/main_lxc.go @@ -48,7 +48,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { return fmt.Errorf("Unknown generator '%s'", file.Generator) } - if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant) { + if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant, c.global.definition.Targets.Type, false) { continue } @@ -66,7 +66,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { } // Run post files hook - for _, action := range c.global.definition.GetRunnableActions("post-files") { + for _, action := range c.global.definition.GetRunnableActions("post-files", false) { err := shared.RunScript(action.Action) if err != nil { exitChroot() diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go index 73596bb..2d2ec5c 100644 --- a/distrobuilder/main_lxd.go +++ b/distrobuilder/main_lxd.go @@ -68,7 +68,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { c.global.flagCacheDir, *c.global.definition) for _, file := range c.global.definition.Files { - if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant) { + if !shared.ApplyFilter(&file, c.global.definition.Image.Release, c.global.definition.Image.ArchitectureMapped, c.global.definition.Image.Variant, c.global.definition.Targets.Type, false) { continue } @@ -91,7 +91,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { } // Run post files hook - for _, action := range c.global.definition.GetRunnableActions("post-files") { + for _, action := range c.global.definition.GetRunnableActions("post-files", false) { err := shared.RunScript(action.Action) if err != nil { exitChroot() diff --git a/shared/definition.go b/shared/definition.go index 23a4006..d3abca7 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -459,7 +459,7 @@ func (d *Definition) Validate() error { // GetRunnableActions returns a list of actions depending on the trigger // and releases. -func (d *Definition) GetRunnableActions(trigger string) []DefinitionAction { +func (d *Definition) GetRunnableActions(trigger string, vmOnly bool) []DefinitionAction { out := []DefinitionAction{} for _, action := range d.Actions { @@ -467,7 +467,7 @@ func (d *Definition) GetRunnableActions(trigger string) []DefinitionAction { continue } - if !ApplyFilter(&action, d.Image.Release, d.Image.ArchitectureMapped, d.Image.Variant) { + if !ApplyFilter(&action, d.Image.Release, d.Image.ArchitectureMapped, d.Image.Variant, d.Targets.Type, vmOnly) { continue } @@ -485,7 +485,7 @@ func (d *Definition) GetEarlyPackages(action string) []string { normal := []DefinitionPackagesSet{} for _, set := range d.Packages.Sets { - if set.Early && set.Action == action && ApplyFilter(&set, d.Image.Release, d.Image.ArchitectureMapped, d.Image.Variant) { + if set.Early && set.Action == action && ApplyFilter(&set, d.Image.Release, d.Image.ArchitectureMapped, d.Image.Variant, d.Targets.Type, false) { early = append(early, set.Packages...) } else { normal = append(normal, set) @@ -563,7 +563,7 @@ func getFieldByTag(v reflect.Value, t reflect.Type, tag string) (reflect.Value, } // ApplyFilter returns true if the filter matches. -func ApplyFilter(filter Filter, release string, architecture string, variant string) bool { +func ApplyFilter(filter Filter, release string, architecture string, variant string, targetType string, vmOnly bool) bool { if len(filter.GetReleases()) > 0 && !shared.StringInSlice(release, filter.GetReleases()) { return false } @@ -576,5 +576,19 @@ func ApplyFilter(filter Filter, release string, architecture string, variant str return false } + types := filter.GetTypes() + + if vmOnly { + if len(types) == 1 && types[0] == "vm" && targetType == "vm" { + return true + } + + return false + } + + if len(types) > 0 && !shared.StringInSlice(targetType, types) { + return false + } + return true } diff --git a/shared/definition_test.go b/shared/definition_test.go index 6186501..6238620 100644 --- a/shared/definition_test.go +++ b/shared/definition_test.go @@ -510,7 +510,29 @@ func TestApplyFilter(t *testing.T) { repo.Variants = []string{"default"} repo.Architectures = []string{"amd64", "i386"} repo.Releases = []string{"foo"} + repo.Types = []string{"vm"} - require.True(t, ApplyFilter(&repo, "foo", "amd64", "default")) - require.False(t, ApplyFilter(&repo, "", "arm64", "default")) + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", true)) + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", false)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", false)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", true)) + require.False(t, ApplyFilter(&repo, "", "arm64", "default", "vm", false)) + + repo.Types = []string{"container"} + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", true)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", false)) + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", false)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", true)) + + repo.Types = []string{"container", "vm"} + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", false)) + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", false)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", true)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", true)) + + repo.Types = []string{} + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", false)) + require.True(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", false)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "container", true)) + require.False(t, ApplyFilter(&repo, "foo", "amd64", "default", "vm", true)) } From e5d467b3c1333c5ea028ece42e8adece2e8d0c5c Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Fri, 14 Feb 2020 11:54:41 +0100 Subject: [PATCH 7/7] distrobuilder: Use overlayfs Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- distrobuilder/chroot.go | 57 +++++++++++++++++++++++++++++++++++++++ distrobuilder/main_lxc.go | 15 ++++++++--- distrobuilder/main_lxd.go | 14 +++++++--- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/distrobuilder/chroot.go b/distrobuilder/chroot.go index a723d54..1e37dba 100644 --- a/distrobuilder/chroot.go +++ b/distrobuilder/chroot.go @@ -2,8 +2,13 @@ package main import ( "fmt" + "os" + "path/filepath" "strings" + "github.com/pkg/errors" + "golang.org/x/sys/unix" + "github.com/lxc/distrobuilder/managers" "github.com/lxc/distrobuilder/shared" ) @@ -138,3 +143,55 @@ func optimizePackageSets(sets []shared.DefinitionPackagesSet) []shared.Definitio return newSets } + +func getOverlay(cacheDir, sourceDir string) (func(), string, error) { + upperDir := filepath.Join(cacheDir, "upper") + overlayDir := filepath.Join(cacheDir, "overlay") + workDir := filepath.Join(cacheDir, "work") + + err := os.Mkdir(upperDir, 0755) + if err != nil { + return nil, "", err + } + + err = os.Mkdir(overlayDir, 0755) + if err != nil { + return nil, "", err + } + + err = os.Mkdir(workDir, 0755) + if err != nil { + return nil, "", err + } + + opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", sourceDir, upperDir, workDir) + + err = unix.Mount("overlay", overlayDir, "overlay", 0, opts) + if err != nil { + return nil, "", err + } + + cleanup := func() { + err := unix.Unmount(overlayDir, 0) + if err != nil { + fmt.Fprintln(os.Stderr, errors.Wrap(err, "Failed to unmount overlay")) + } + + err = os.RemoveAll(upperDir) + if err != nil { + fmt.Fprintln(os.Stderr, errors.Wrap(err, "Failed to remove upper directory")) + } + + err = os.RemoveAll(workDir) + if err != nil { + fmt.Fprintln(os.Stderr, errors.Wrap(err, "Failed to remove work directory")) + } + + err = os.Remove(overlayDir) + if err != nil { + fmt.Fprintln(os.Stderr, errors.Wrap(err, "Failed to remove overlay directory")) + } + } + + return cleanup, overlayDir, nil +} diff --git a/distrobuilder/main_lxc.go b/distrobuilder/main_lxc.go index 0990d32..00731b8 100644 --- a/distrobuilder/main_lxc.go +++ b/distrobuilder/main_lxc.go @@ -3,6 +3,7 @@ package main import ( "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/lxc/distrobuilder/generators" @@ -39,7 +40,13 @@ func (c *cmdLXC) commandPack() *cobra.Command { } func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { - img := image.NewLXCImage(c.global.sourceDir, c.global.targetDir, + cleanup, overlayDir, err := getOverlay(c.global.flagCacheDir, c.global.sourceDir) + if err != nil { + return errors.Wrap(err, "Failed to create overlay") + } + defer cleanup() + + img := image.NewLXCImage(overlayDir, c.global.targetDir, c.global.flagCacheDir, *c.global.definition) for _, file := range c.global.definition.Files { @@ -52,14 +59,14 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { continue } - err := generator.RunLXC(c.global.flagCacheDir, c.global.sourceDir, img, + err := generator.RunLXC(c.global.flagCacheDir, overlayDir, img, file) if err != nil { return err } } - exitChroot, err := shared.SetupChroot(c.global.sourceDir, + exitChroot, err := shared.SetupChroot(overlayDir, c.global.definition.Environment, nil) if err != nil { return err @@ -82,7 +89,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { } // Clean up the chroot by restoring the orginal files. - err = generators.RestoreFiles(c.global.flagCacheDir, c.global.sourceDir) + err = generators.RestoreFiles(c.global.flagCacheDir, overlayDir) if err != nil { return fmt.Errorf("Failed to restore cached files: %s", err) } diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go index 2d2ec5c..8823f39 100644 --- a/distrobuilder/main_lxd.go +++ b/distrobuilder/main_lxd.go @@ -1,10 +1,10 @@ package main import ( - "errors" "fmt" lxd "github.com/lxc/lxd/shared" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/lxc/distrobuilder/generators" @@ -64,7 +64,13 @@ func (c *cmdLXD) commandPack() *cobra.Command { } func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { - img := image.NewLXDImage(c.global.sourceDir, c.global.targetDir, + cleanup, overlayDir, err := getOverlay(c.global.flagCacheDir, c.global.sourceDir) + if err != nil { + return errors.Wrap(err, "Failed to create overlay") + } + defer cleanup() + + img := image.NewLXDImage(overlayDir, c.global.targetDir, c.global.flagCacheDir, *c.global.definition) for _, file := range c.global.definition.Files { @@ -77,14 +83,14 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { return fmt.Errorf("Unknown generator '%s'", file.Generator) } - err := generator.RunLXD(c.global.flagCacheDir, c.global.sourceDir, + err := generator.RunLXD(c.global.flagCacheDir, overlayDir, img, file) if err != nil { return fmt.Errorf("Failed to create LXD data: %s", err) } } - exitChroot, err := shared.SetupChroot(c.global.sourceDir, + exitChroot, err := shared.SetupChroot(overlayDir, c.global.definition.Environment, nil) if err != nil { return err
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel