[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