[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