[lxc-devel] [distrobuilder/master] VM preparations
monstermunchkin on Github
lxc-bot at linuxcontainers.org
Fri Feb 14 11:03:57 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 365 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200214/9a5db6b2/attachment.bin>
-------------- next part --------------
From 65112ce0b9a49cb33fbec289e38135ff9577be25 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at 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.hipp at canonical.com>
Date: Wed, 12 Feb 2020 17:37:30 +0100
Subject: [PATCH 6/7] *: Support VM filtering
Signed-off-by: Thomas Hipp <thomas.hipp at 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.hipp at canonical.com>
Date: Fri, 14 Feb 2020 11:54:41 +0100
Subject: [PATCH 7/7] distrobuilder: Use overlayfs
Signed-off-by: Thomas Hipp <thomas.hipp at 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
More information about the lxc-devel
mailing list