[lxc-devel] [distrobuilder/master] Support Oracle Linux

monstermunchkin on Github lxc-bot at linuxcontainers.org
Mon Feb 25 15:25:27 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 329 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190225/ffd42015/attachment.bin>
-------------- next part --------------
From bfc8e56d375c0abe2f90f589fcf8a7bf6969aba4 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 25 Feb 2019 15:16:07 +0100
Subject: [PATCH 1/3] sources: Add Oracle Linux

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 sources/oraclelinux-http.go | 185 ++++++++++++++++++++++++++++++++++++
 sources/source.go           |   2 +
 2 files changed, 187 insertions(+)
 create mode 100644 sources/oraclelinux-http.go

diff --git a/sources/oraclelinux-http.go b/sources/oraclelinux-http.go
new file mode 100644
index 0000000..6cdb152
--- /dev/null
+++ b/sources/oraclelinux-http.go
@@ -0,0 +1,185 @@
+package sources
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"syscall"
+
+	"gopkg.in/antchfx/htmlquery.v1"
+
+	"github.com/lxc/distrobuilder/shared"
+)
+
+// OracleLinuxHTTP represents the Oracle Linux downloader.
+type OracleLinuxHTTP struct {
+	majorVersion string
+}
+
+// NewOracleLinuxHTTP creates a new OracleLinuxHTTP instance.
+func NewOracleLinuxHTTP() *OracleLinuxHTTP {
+	return &OracleLinuxHTTP{}
+}
+
+// Run downloads Oracle Linux.
+func (s *OracleLinuxHTTP) Run(definition shared.Definition, rootfsDir string) error {
+	s.majorVersion = definition.Image.Release
+	fname := "x86_64-boot.iso"
+	baseURL := fmt.Sprintf("%s/OL%s", definition.Source.URL, definition.Image.Release)
+
+	latestUpdate, err := s.getLatestUpdate(baseURL)
+	if err != nil {
+		return err
+	}
+
+	err = shared.DownloadHash(fmt.Sprintf("%s/u%s/x86_64/%s", baseURL, latestUpdate, fname),
+		"", nil)
+	if err != nil {
+		return fmt.Errorf("Error downloading Oracle Linux image: %s", err)
+	}
+
+	return s.unpackISO(latestUpdate, filepath.Join(os.TempDir(), fname), rootfsDir)
+}
+
+func (s *OracleLinuxHTTP) unpackISO(latestUpdate, filePath, rootfsDir string) error {
+	isoDir := filepath.Join(os.TempDir(), "distrobuilder", "iso")
+	squashfsDir := filepath.Join(os.TempDir(), "distrobuilder", "squashfs")
+	roRootDir := filepath.Join(os.TempDir(), "distrobuilder", "rootfs.ro")
+	tempRootDir := filepath.Join(os.TempDir(), "distrobuilder", "rootfs")
+
+	os.MkdirAll(isoDir, 0755)
+	os.MkdirAll(squashfsDir, 0755)
+	os.MkdirAll(roRootDir, 0755)
+	defer os.RemoveAll(filepath.Join(os.TempDir(), "distrobuilder"))
+
+	// this is easier than doing the whole loop thing ourselves
+	err := shared.RunCommand("mount", "-o", "ro", filePath, isoDir)
+	if err != nil {
+		return err
+	}
+	defer syscall.Unmount(isoDir, 0)
+
+	var rootfsImage string
+	squashfsImage := filepath.Join(isoDir, "LiveOS", "squashfs.img")
+
+	// The squashfs.img contains an image containing the rootfs, so first
+	// mount squashfs.img
+	err = shared.RunCommand("mount", "-o", "ro", squashfsImage, squashfsDir)
+	if err != nil {
+		return err
+	}
+	defer syscall.Unmount(squashfsDir, 0)
+
+	rootfsImage = filepath.Join(squashfsDir, "LiveOS", "rootfs.img")
+
+	err = shared.RunCommand("mount", "-o", "ro", rootfsImage, roRootDir)
+	if err != nil {
+		return err
+	}
+	defer syscall.Unmount(roRootDir, 0)
+
+	// Remove rootfsDir otherwise rsync will copy the content into the directory
+	// itself
+	err = os.RemoveAll(rootfsDir)
+	if err != nil {
+		return err
+	}
+
+	// Since roRootDir is read-only, we need to copy it to a temporary rootfs
+	// directory in order to create the minimal rootfs.
+	err = shared.RunCommand("rsync", "-qa", roRootDir+"/", tempRootDir)
+	if err != nil {
+		return err
+	}
+
+	// Setup the mounts and chroot into the rootfs
+	exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{})
+	if err != nil {
+		return fmt.Errorf("Failed to setup chroot: %s", err)
+	}
+
+	err = shared.RunScript(fmt.Sprintf(`
+#!/bin/sh
+set -eux
+
+version="%s"
+update="%s"
+
+# Create required files
+touch /etc/mtab /etc/fstab
+
+# Fetch and install rpm and yum from the Oracle repo
+_rpm=$(curl -s https://yum.oracle.com/repo/OracleLinux/OL${version}/${update}/base/x86_64/index.html | grep -Eo '>rpm-[[:digit:]][^ ]+\.rpm<' | tail -1 | tr -d '<>')
+_yum=$(curl -s https://yum.oracle.com/repo/OracleLinux/OL${version}/${update}/base/x86_64/index.html | grep -Eo '>yum-[[:digit:]][^ ]+\.rpm<' | tail -1 | tr -d '<>')
+
+wget https://yum.oracle.com/repo/OracleLinux/OL${version}/${update}/base/x86_64/getPackage/${_rpm}
+wget https://yum.oracle.com/repo/OracleLinux/OL${version}/${update}/base/x86_64/getPackage/${_yum}
+
+# There's no OL7 key!
+wget https://oss.oracle.com/ol6/RPM-GPG-KEY-oracle
+
+rpm -ivh --nodeps "${_rpm}" "${_yum}"
+rpm --import RPM-GPG-KEY-oracle
+
+# Add repo
+mkdir -p /etc/yum.repos.d
+cat <<- EOF > /etc/yum.repos.d/base.repo
+[base]
+name=Oracle Linux
+baseurl=https://yum.oracle.com/repo/OracleLinux/OL${version}/${update}/base/x86_64
+enabled=1
+gpgcheck=1
+gpgkey=file:///RPM-GPG-KEY-oracle
+EOF
+
+mkdir /rootfs
+yum --installroot=/rootfs -y --releasever=${version} install basesystem oraclelinux-release yum
+rm -rf /rootfs/var/cache/yum
+
+cp RPM-GPG-KEY-oracle /rootfs
+
+mkdir -p /rootfs/etc/yum.repos.d
+cat <<- EOF > /rootfs/etc/yum.repos.d/base.repo
+[base]
+name=Oracle Linux
+baseurl=https://yum.oracle.com/repo/OracleLinux/OL${version}/${update}/base/x86_64
+enabled=1
+gpgcheck=1
+gpgkey=file:///RPM-GPG-KEY-oracle
+EOF
+`, s.majorVersion, latestUpdate))
+	if err != nil {
+		exitChroot()
+		return err
+	}
+
+	exitChroot()
+
+	return shared.RunCommand("rsync", "-qa", tempRootDir+"/rootfs/", rootfsDir)
+}
+
+func (s *OracleLinuxHTTP) getLatestUpdate(URL string) (string, error) {
+	re := regexp.MustCompile(`^u\d+/$`)
+
+	doc, err := htmlquery.LoadURL(URL)
+	if err != nil {
+		return "", err
+	}
+
+	var latestUpdate string
+
+	for _, a := range htmlquery.Find(doc, "//a/@href") {
+		if re.MatchString(a.FirstChild.Data) {
+			latestUpdate = a.FirstChild.Data
+		}
+	}
+
+	if latestUpdate == "" {
+		return "", fmt.Errorf("No update found")
+	}
+
+	latestUpdate = strings.TrimPrefix(latestUpdate, "u")
+	return strings.TrimSuffix(latestUpdate, "/"), nil
+}
diff --git a/sources/source.go b/sources/source.go
index 28c1b08..7ec368b 100644
--- a/sources/source.go
+++ b/sources/source.go
@@ -28,6 +28,8 @@ func Get(name string) Downloader {
 		return NewSabayonHTTP()
 	case "docker-http":
 		return NewDockerHTTP()
+	case "oraclelinux-http":
+		return NewOracleLinuxHTTP()
 	}
 
 	return nil

From 36618194ae575df4a0684873f9df94ee34259f3e Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 25 Feb 2019 15:57:24 +0100
Subject: [PATCH 2/3] shared: Add Oracle Linux

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 shared/definition.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/shared/definition.go b/shared/definition.go
index 33fa9e3..0ea231b 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -239,6 +239,7 @@ func (d *Definition) Validate() error {
 		"ubuntu-http",
 		"sabayon-http",
 		"docker-http",
+		"oraclelinux-http",
 	}
 	if !shared.StringInSlice(strings.TrimSpace(d.Source.Downloader), validDownloaders) {
 		return fmt.Errorf("source.downloader must be one of %v", validDownloaders)

From 1d75b934ee1f9c90a282da4fffa38b088f9a3f53 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 25 Feb 2019 15:57:37 +0100
Subject: [PATCH 3/3] doc: Add Oracle Linux

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 doc/examples/oraclelinux | 156 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)
 create mode 100644 doc/examples/oraclelinux

diff --git a/doc/examples/oraclelinux b/doc/examples/oraclelinux
new file mode 100644
index 0000000..f7bbff6
--- /dev/null
+++ b/doc/examples/oraclelinux
@@ -0,0 +1,156 @@
+image:
+  distribution: oraclelinux
+  release: 7
+
+source:
+  downloader: oraclelinux-http
+  url: https://mirror.aarnet.edu.au/pub/oraclelinux
+
+targets:
+  lxc:
+    create-message: |
+        You just created a {{ image.description }} container.
+
+    config:
+      - type: all
+        before: 5
+        content: |-
+          lxc.include = LXC_TEMPLATE_CONFIG/oraclelinux.common.conf
+
+      - type: user
+        before: 5
+        content: |-
+          lxc.include = LXC_TEMPLATE_CONFIG/oraclelinux.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:
+ - name: hostname
+   path: /etc/hostname
+   generator: hostname
+
+ - name: hosts
+   path: /etc/hosts
+   generator: hosts
+
+ - name: ifcfg-eth0
+   path: /etc/sysconfig/network-scripts/ifcfg-eth0
+   generator: dump
+   templated: true
+   content: |-
+     DEVICE=eth0
+     BOOTPROTO=dhcp
+     ONBOOT=yes
+     HOSTNAME=LXC_NAME
+     NM_CONTROLLED=no
+     TYPE=Ethernet
+     MTU=
+     DHCP_HOSTNAME=`hostname`
+
+ - name: network
+   path: /etc/sysconfig/network
+   generator: dump
+   templated: true
+   content: |-
+     NETWORKING=yes
+     HOSTNAME=LXC_NAME
+
+ - name: ifcfg-eth0.lxd
+   path: /etc/sysconfig/network-scripts/ifcfg-eth0
+   generator: template
+   content: |-
+     DEVICE=eth0
+     BOOTPROTO=dhcp
+     ONBOOT=yes
+     HOSTNAME={{ container.name }}
+     NM_CONTROLLED=no
+     TYPE=Ethernet
+     MTU=
+     DHCP_HOSTNAME=`hostname`
+
+ - name: network.lxd
+   path: /etc/sysconfig/network
+   generator: template
+   content: |-
+     NETWORKING=yes
+     HOSTNAME={{ container.name }}
+
+ - name: lxc-sysinit
+   path: /etc/init/lxc-sysinit.conf
+   generator: dump
+   content: |-
+     start on startup
+     env container
+
+     pre-start script
+         if [ "x$container" != "xlxc" -a "x$container" != "xlibvirt" ]; then
+             stop;
+         fi
+
+         rm -f /var/lock/subsys/*
+         rm -f /var/run/*.pid
+         [ -e /etc/mtab ] || ln -s /proc/mounts /etc/mtab
+         mkdir -p /dev/shm
+         mount -t tmpfs -o nosuid,nodev tmpfs /dev/shm
+
+         initctl start tty TTY=console
+         telinit 3
+         exit 0
+     end script
+   releases:
+    - 6
+
+ - name: sigpwr.conf
+   path: /etc/init/power-status-changed.conf
+   generator: dump
+   content: |-
+     start on power-status-changed
+
+     exec /sbin/shutdown -h now "SIGPWR received"
+   releases:
+    - 6
+
+packages:
+    manager: yum
+    update: true
+    cleanup: true
+
+    sets:
+     - packages:
+        - cronie
+        - cronie-noanacron
+        - curl
+        - dhclient
+        - initscripts
+        - openssh-clients
+        - passwd
+        - policycoreutils
+        - rootfiles
+        - rsyslog
+        - vim-minimal
+       action: install
+
+actions:
+  - trigger: post-packages
+    action: |-
+      #!/bin/sh
+      set -eux
+
+      # Disable SELinux
+      mkdir -p /selinux
+      echo 0 > /selinux/enforce
+
+      # Disable loginuid in PAM stack
+      sed -i '/^session.*pam_loginuid.so/s/^session/# session/' /etc/pam.d/*


More information about the lxc-devel mailing list