[lxc-devel] [distrobuilder/master] Add sabayon support and new features
geaaru on Github
lxc-bot at linuxcontainers.org
Sun Dec 9 23:03:06 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 409 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181209/e2c4887b/attachment.bin>
-------------- next part --------------
From c20531d122cd8b46c4478f516520a80e2758ae3b Mon Sep 17 00:00:00 2001
From: Daniele Rondina <geaaru at sabayonlinux.org>
Date: Sun, 9 Dec 2018 16:31:04 +0100
Subject: [PATCH 1/3] Permit definition of environment vars on image file
---
distrobuilder/main.go | 2 +-
distrobuilder/main_lxc.go | 3 ++-
distrobuilder/main_lxd.go | 3 ++-
shared/chroot.go | 22 ++++++++++++++++++----
shared/definition.go | 21 ++++++++++++++-------
sources/alpine-http.go | 2 +-
6 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/distrobuilder/main.go b/distrobuilder/main.go
index ed14548..c060e60 100644
--- a/distrobuilder/main.go
+++ b/distrobuilder/main.go
@@ -197,7 +197,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)
+ exitChroot, err := shared.SetupChroot(c.sourceDir, c.definition.EnvVariables)
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 86cb4d2..1e75156 100644
--- a/distrobuilder/main_lxc.go
+++ b/distrobuilder/main_lxc.go
@@ -66,7 +66,8 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error {
}
}
- exitChroot, err := shared.SetupChroot(c.global.sourceDir)
+ exitChroot, err := shared.SetupChroot(c.global.sourceDir,
+ c.global.definition.EnvVariables)
if err != nil {
return err
}
diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go
index 3a33696..c6c3894 100644
--- a/distrobuilder/main_lxd.go
+++ b/distrobuilder/main_lxd.go
@@ -85,7 +85,8 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error {
}
}
- exitChroot, err := shared.SetupChroot(c.global.sourceDir)
+ exitChroot, err := shared.SetupChroot(c.global.sourceDir,
+ c.global.definition.EnvVariables)
if err != nil {
return err
}
diff --git a/shared/chroot.go b/shared/chroot.go
index 0b28201..37a62cc 100644
--- a/shared/chroot.go
+++ b/shared/chroot.go
@@ -147,7 +147,7 @@ func killChrootProcesses(rootfs string) error {
}
// SetupChroot sets up mount and files, a reverter and then chroots for you
-func SetupChroot(rootfs string) (func() error, error) {
+func SetupChroot(rootfs string, envs []DefinitionEnvVars) (func() error, error) {
// Mount the rootfs
err := syscall.Mount(rootfs, rootfs, "", syscall.MS_BIND, "")
if err != nil {
@@ -200,8 +200,10 @@ func SetupChroot(rootfs string) (func() error, error) {
}
// Set environment variables
- oldEnvVariables := SetEnvVariables(
- []EnvVariable{
+ var env_vars []EnvVariable = []EnvVariable{}
+
+ if envs == nil || len(envs) == 0 {
+ env_vars = []EnvVariable{
{
Key: "PATH",
Value: "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
@@ -222,7 +224,19 @@ func SetupChroot(rootfs string) (func() error, error) {
Value: "noninteractive",
Set: true,
},
- })
+ }
+
+ } else {
+ for _, env := range envs {
+ env_vars = append(env_vars, EnvVariable{
+ Key: env.Key,
+ Value: env.Value,
+ Set: true,
+ })
+ }
+ }
+
+ oldEnvVariables := SetEnvVariables(env_vars)
// Setup policy-rc.d override
policyCleanup := false
diff --git a/shared/definition.go b/shared/definition.go
index f3b78de..b579349 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -103,15 +103,22 @@ type DefinitionMappings struct {
ArchitectureMap string `yaml:"architecture_map,omitempty"`
}
+// DefinitionEnvVars defines custom environment variables.
+type DefinitionEnvVars struct {
+ Key string `yaml:"key"`
+ Value string `yaml:"value"`
+}
+
// A Definition a definition.
type Definition struct {
- Image DefinitionImage `yaml:"image"`
- Source DefinitionSource `yaml:"source"`
- Targets DefinitionTarget `yaml:"targets,omitempty"`
- Files []DefinitionFile `yaml:"files,omitempty"`
- Packages DefinitionPackages `yaml:"packages,omitempty"`
- Actions []DefinitionAction `yaml:"actions,omitempty"`
- Mappings DefinitionMappings `yaml:"mappings,omitempty"`
+ Image DefinitionImage `yaml:"image"`
+ Source DefinitionSource `yaml:"source"`
+ Targets DefinitionTarget `yaml:"targets,omitempty"`
+ Files []DefinitionFile `yaml:"files,omitempty"`
+ Packages DefinitionPackages `yaml:"packages,omitempty"`
+ Actions []DefinitionAction `yaml:"actions,omitempty"`
+ Mappings DefinitionMappings `yaml:"mappings,omitempty"`
+ EnvVariables []DefinitionEnvVars `yaml:"environment"`
}
// SetValue writes the provided value to a field represented by the yaml tag 'key'.
diff --git a/sources/alpine-http.go b/sources/alpine-http.go
index f465094..9ff6285 100644
--- a/sources/alpine-http.go
+++ b/sources/alpine-http.go
@@ -95,7 +95,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)
+ exitChroot, err := shared.SetupChroot(rootfsDir, nil)
if err != nil {
return err
}
From e9ae2e0cc41751f6e1adfece599a508022d2469e Mon Sep 17 00:00:00 2001
From: Daniele Rondina <geaaru at sabayonlinux.org>
Date: Sun, 9 Dec 2018 16:41:34 +0100
Subject: [PATCH 2/3] Added sabayon amd64 support
---
doc/examples/sabayon | 102 +++++++++++++++++++++++++++++++++++++++++++
managers/equo.go | 26 +++++++++++
managers/manager.go | 2 +
shared/definition.go | 2 +
sources/sabayon.go | 44 +++++++++++++++++++
sources/source.go | 2 +
6 files changed, 178 insertions(+)
create mode 100644 doc/examples/sabayon
create mode 100644 managers/equo.go
create mode 100644 sources/sabayon.go
diff --git a/doc/examples/sabayon b/doc/examples/sabayon
new file mode 100644
index 0000000..f58f181
--- /dev/null
+++ b/doc/examples/sabayon
@@ -0,0 +1,102 @@
+image:
+ distribution: sabayon
+ decription: Sabayon
+ expiry: 30d
+ architecture: amd64
+
+source:
+ downloader: sabayon-http
+ url: http://dl.sabayon.org/sbi/sabayon%3Aiso/iso
+
+environment:
+ - key: "PATH"
+ value: "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
+ - key: "SHELL"
+ value: "/bin/sh"
+ - key: "TERM"
+ value: "xterm"
+ - key: "ACCEPT_LICENSE"
+ value: "*"
+
+targets:
+ lxc:
+ create-message: |
+ You just created a Sabayon container (arch={{ image.architecture }})
+
+ config:
+ - type: all
+ before: 5
+ content: |-
+ lxc.include = LXC_TEMPLATE_CONFIG/sabayon.common.conf
+
+ - type: user
+ before: 5
+ content: |-
+ lxc.include = LXC_TEMPLATE_CONFIG/sabayon.userns.conf
+
+ - type: all
+ after: 4
+ content: |-
+ lxc.include = LXC_TEMPLATE_CONFIG/common.conf
+
+ - type: user
+ after: 4
+ content: |-
+ lxc.include = LXC_TEMPLATE_CONFIG/userns.conf
+
+ - type: all
+ content: |-
+ lxc.arch = {{ image.architecture_kernel }}
+
+files:
+ - path: /etc/hostname
+ generator: hostname
+
+ - path: /etc/hosts
+ generator: hosts
+
+packages:
+ manager: equo
+ update: true
+ cleanup: true
+ install:
+ - sabayon-live
+
+actions:
+ - trigger: post-packages
+ action: |-
+ #!/bin/sh
+ echo -5 | equo conf update
+
+ # Disable systemd-remount-fs.service because
+ # on unprivileged container systemd can't
+ # remount filesystem.
+ - trigger: post-packages
+ action: |-
+ #!/bin/sh
+ cd /etc/systemd/system
+ ln -s /dev/null systemd-remount-fs.service
+
+ # Disable mount of hugepages
+ - trigger: post-packages
+ action: |-
+ #!/bin/bash
+ cd /etc/systemd/system
+ ln -s /dev/null dev-hugepages.mount
+
+ # Disable sabayon-anti-fork-bomb limits
+ # (already apply to host)
+ - trigger: post-packages
+ action: |-
+ #!/bin/bash
+ sed -i -e 's/^*/#*/g' /etc/security/limits.d/00-sabayon-anti-fork-bomb.conf
+ sed -i -e 's/^root/#root/g' /etc/security/limits.d/00-sabayon-anti-fork-bomb.conf
+
+ # Clean journal directory (to avoid permission errors)
+ - trigger: post-packages
+ action: |-
+ rm -rf /var/log/journal/
+
+mappings:
+ architecture_map: debian
+
diff --git a/managers/equo.go b/managers/equo.go
new file mode 100644
index 0000000..dc8ef6d
--- /dev/null
+++ b/managers/equo.go
@@ -0,0 +1,26 @@
+package managers
+
+// NewEquo creates a new Manager instance
+func NewEquo() *Manager {
+ return &Manager{
+ command: "equo",
+ flags: ManagerFlags{
+ global: []string{},
+ clean: []string{
+ "cleanup",
+ },
+ install: []string{
+ "install",
+ },
+ remove: []string{
+ "remove",
+ },
+ refresh: []string{
+ "update",
+ },
+ update: []string{
+ "upgrade",
+ },
+ },
+ }
+}
diff --git a/managers/manager.go b/managers/manager.go
index 17ebacf..18e83d6 100644
--- a/managers/manager.go
+++ b/managers/manager.go
@@ -39,6 +39,8 @@ func Get(name string) *Manager {
return NewPortage()
case "yum":
return NewYum()
+ case "equo":
+ return NewEquo()
}
return nil
diff --git a/shared/definition.go b/shared/definition.go
index b579349..501272e 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -214,6 +214,7 @@ func (d *Definition) Validate() error {
"fedora-http",
"gentoo-http",
"ubuntu-http",
+ "sabayon-http",
}
if !shared.StringInSlice(strings.TrimSpace(d.Source.Downloader), validDownloaders) {
return fmt.Errorf("source.downloader must be one of %v", validDownloaders)
@@ -226,6 +227,7 @@ func (d *Definition) Validate() error {
"pacman",
"portage",
"yum",
+ "equo",
}
if !shared.StringInSlice(strings.TrimSpace(d.Packages.Manager), validManagers) {
return fmt.Errorf("packages.manager must be one of %v", validManagers)
diff --git a/sources/sabayon.go b/sources/sabayon.go
new file mode 100644
index 0000000..4a3614c
--- /dev/null
+++ b/sources/sabayon.go
@@ -0,0 +1,44 @@
+package sources
+
+import (
+ "fmt"
+ "net/url"
+ "os"
+ "path/filepath"
+
+ lxd "github.com/lxc/lxd/shared"
+
+ "github.com/lxc/distrobuilder/shared"
+)
+
+type SabayonHTTP struct{}
+
+// NewSabayonHTTP creates a new SabayonHTTP instance.
+func NewSabayonHTTP() *SabayonHTTP {
+ return &SabayonHTTP{}
+}
+
+// Run downloads a Sabayon tarball.
+func (s *SabayonHTTP) Run(definition shared.Definition, rootfsDir string) error {
+ fname := fmt.Sprintf("Sabayon_Linux_DAILY_%s_tarball.tar.gz",
+ definition.Image.ArchitectureMapped)
+ tarball := fmt.Sprintf("%s/%s", definition.Source.URL, fname)
+ _, err := url.Parse(tarball)
+ if err != nil {
+ return err
+ }
+
+ // Temporary Skip verification. From sabayon currently we have only MD5 checksum.
+ err = shared.DownloadSha512(tarball, "")
+ if err != nil {
+ return err
+ }
+
+ // Unpack
+ err = lxd.Unpack(filepath.Join(os.TempDir(), fname), rootfsDir, false, false)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/sources/source.go b/sources/source.go
index d84f4fe..0ed45e8 100644
--- a/sources/source.go
+++ b/sources/source.go
@@ -24,6 +24,8 @@ func Get(name string) Downloader {
return NewGentooHTTP()
case "ubuntu-http":
return NewUbuntuHTTP()
+ case "sabayon-http":
+ return NewSabayonHTTP()
}
return nil
From fe2b8ebd8ee8f3ac5dd3e8e9ce34eb68a254bbb9 Mon Sep 17 00:00:00 2001
From: Daniele Rondina <geaaru at sabayonlinux.org>
Date: Sun, 9 Dec 2018 23:55:24 +0100
Subject: [PATCH 3/3] Integrate repositories handler function
Signed-off-by: Daniele Rondina <geaaru at sabayonlinux.org>
---
distrobuilder/chroot.go | 15 ++++++++
doc/examples/sabayon | 15 ++++++++
managers/equo.go | 83 +++++++++++++++++++++++++++++++++++++++++
managers/manager.go | 7 ++--
shared/definition.go | 19 ++++++++--
5 files changed, 132 insertions(+), 7 deletions(-)
diff --git a/distrobuilder/chroot.go b/distrobuilder/chroot.go
index de3e0fd..5ca84d5 100644
--- a/distrobuilder/chroot.go
+++ b/distrobuilder/chroot.go
@@ -15,6 +15,21 @@ func managePackages(def shared.DefinitionPackages, actions []shared.DefinitionAc
return fmt.Errorf("Couldn't get manager")
}
+ // Handle repositories actions
+ if def.Repositories != nil && len(def.Repositories) > 0 {
+ if manager.RepoHandler == nil {
+ return fmt.Errorf("No repository handler present!")
+ }
+
+ for _, repo := range def.Repositories {
+ err = manager.RepoHandler(repo)
+ if err != nil {
+ return fmt.Errorf(
+ fmt.Sprintf("Error for repository %s: %s", repo.Name, err))
+ }
+ }
+ }
+
err = manager.Refresh()
if err != nil {
return err
diff --git a/doc/examples/sabayon b/doc/examples/sabayon
index f58f181..aa8ced9 100644
--- a/doc/examples/sabayon
+++ b/doc/examples/sabayon
@@ -57,12 +57,27 @@ files:
packages:
manager: equo
+
+# repositories:
+# - name: "community"
+# type: "enman"
+# action: "add"
+
update: true
cleanup: true
install:
- sabayon-live
actions:
+ # Spinbase image doesn't include enman tool
+ # for external repositories. This is not needed
+ # if external repository aren't used or it's used equ
+ # as repo type.
+ #- trigger: post-unpack
+ # action: |-
+ # #!/bin/sh
+ # equo up && equo i enman
+
- trigger: post-packages
action: |-
#!/bin/sh
diff --git a/managers/equo.go b/managers/equo.go
index dc8ef6d..615dc7c 100644
--- a/managers/equo.go
+++ b/managers/equo.go
@@ -1,5 +1,79 @@
package managers
+import (
+ "fmt"
+
+ "github.com/lxc/distrobuilder/shared"
+)
+
+func enman_repo_caller(repo shared.DefinitionRepository) error {
+ var err error
+ var args []string
+
+ if repo.Action == "" {
+ err = fmt.Errorf("Invalid action!")
+ } else {
+ args = []string{
+ repo.Action,
+ }
+
+ if repo.Action == "add" {
+ if repo.Url != "" {
+ args = append(args, repo.Url)
+ } else {
+ args = append(args, repo.Name)
+ }
+ } else if repo.Action == "remove" ||
+ repo.Action == "enable" || repo.Action == "enable" {
+ args = append(args, repo.Name)
+ } else {
+ err = fmt.Errorf("Invalid Action")
+ }
+ }
+
+ if err == nil {
+ err = shared.RunCommand("enman", args...)
+ }
+
+ return err
+}
+
+func equo_repo_caller(repo shared.DefinitionRepository) error {
+ var args []string = []string{
+ "repo",
+ }
+
+ if repo.Name == "" {
+ return fmt.Errorf("Invalid repository name!")
+ }
+
+ if repo.Url == "" {
+ return fmt.Errorf("Invalid url!")
+ }
+
+ if repo.Action == "" {
+ return fmt.Errorf("Invalid action!")
+ }
+
+ args = append(args, repo.Action)
+
+ if repo.Action == "add" {
+ args = append(args, "--repo")
+ args = append(args, repo.Url)
+ args = append(args, "--pkg")
+ args = append(args, repo.Url)
+ args = append(args, repo.Name)
+
+ } else if repo.Action == "remove" || repo.Action == "enable" ||
+ repo.Action == "enable" {
+ args = append(args, repo.Name)
+ } else {
+ return fmt.Errorf("Invalid Action!")
+ }
+
+ return shared.RunCommand("enman", args...)
+}
+
// NewEquo creates a new Manager instance
func NewEquo() *Manager {
return &Manager{
@@ -22,5 +96,14 @@ func NewEquo() *Manager {
"upgrade",
},
},
+ RepoHandler: func(repoAction shared.DefinitionRepository) error {
+ if repoAction.Type == "" || repoAction.Type == "equo" {
+ return equo_repo_caller(repoAction)
+ } else if repoAction.Type == "enman" {
+ return enman_repo_caller(repoAction)
+ }
+
+ return fmt.Errorf("Invalid repository Type")
+ },
}
}
diff --git a/managers/manager.go b/managers/manager.go
index 18e83d6..0e091eb 100644
--- a/managers/manager.go
+++ b/managers/manager.go
@@ -19,9 +19,10 @@ type ManagerHooks struct {
// A Manager represents a package manager.
type Manager struct {
- command string
- flags ManagerFlags
- hooks ManagerHooks
+ command string
+ flags ManagerFlags
+ hooks ManagerHooks
+ RepoHandler func(repoAction shared.DefinitionRepository) error
}
// Get returns a Manager specified by name.
diff --git a/shared/definition.go b/shared/definition.go
index 501272e..1d80ee7 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -14,13 +14,24 @@ import (
"github.com/lxc/lxd/shared"
)
+// A DefinitionRepository contains data of a specific repository
+type DefinitionRepository struct {
+ Name string `yaml:"name"`
+ Url string `yaml:"url"`
+ // This option is needed only for Sabayon repository
+ // for identify tool to use: enman|equo
+ Type string `yaml:"type"`
+ Action string `yaml:"action"`
+}
+
// A DefinitionPackages list packages which are to be either installed or
// removed.
type DefinitionPackages struct {
- Manager string `yaml:"manager"`
- Install []string `yaml:"install,omitempty"`
- Remove []string `yaml:"remove,omitempty"`
- Update bool `yaml:"update,omitempty"`
+ Manager string `yaml:"manager"`
+ Install []string `yaml:"install,omitempty"`
+ Remove []string `yaml:"remove,omitempty"`
+ Update bool `yaml:"update,omitempty"`
+ Repositories []DefinitionRepository `yaml:"repositories"`
}
// A DefinitionImage represents the image.
More information about the lxc-devel
mailing list