The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/distrobuilder/pull/86

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From b47fd377627bde3addf02560f04a67b3244e09cc Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Thu, 29 Mar 2018 15:38:10 +0200
Subject: [PATCH 1/4] shared,sources: Add functions DownloadSha{256,512}

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 shared/net.go             | 34 ++++++++++++++++++++++++++--------
 sources/alpine-http.go    |  4 ++--
 sources/archlinux-http.go |  4 ++--
 sources/centos-http.go    |  4 ++--
 sources/fedora-http.go    |  2 +-
 sources/ubuntu-http.go    |  6 +++---
 6 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/shared/net.go b/shared/net.go
index 84dcb78..589f984 100644
--- a/shared/net.go
+++ b/shared/net.go
@@ -3,7 +3,9 @@ package shared
 import (
        "bufio"
        "crypto/sha256"
+       "crypto/sha512"
        "fmt"
+       "hash"
        "io"
        "io/ioutil"
        "net/http"
@@ -16,9 +18,19 @@ import (
        "github.com/lxc/lxd/shared/ioprogress"
 )
 
-// Download downloads a file. If a checksum file is provided will try and match
-// the hash.
-func Download(file, checksum string) error {
+// DownloadSha256 downloads a file. If a checksum file is provided will try and
+// match the sha256 hash.
+func DownloadSha256(file, checksum string) error {
+       return download(file, checksum, sha256.New())
+}
+
+// DownloadSha512 downloads a file. If a checksum file is provided will try and
+// match the sha512 hash.
+func DownloadSha512(file, checksum string) error {
+       return download(file, checksum, sha512.New())
+}
+
+func download(file, checksum string, sha hash.Hash) error {
        var (
                client http.Client
                hash   string
@@ -43,13 +55,12 @@ func Download(file, checksum string) error {
                defer image.Close()
 
                if checksum != "" {
-                       sha256 := sha256.New()
-                       _, err = io.Copy(sha256, image)
+                       _, err = io.Copy(sha, image)
                        if err != nil {
                                return err
                        }
 
-                       result := fmt.Sprintf("%x", sha256.Sum(nil))
+                       result := fmt.Sprintf("%x", sha.Sum(nil))
                        if result != hash {
                                return fmt.Errorf("Hash mismatch for %s: %s != 
%s", imagePath, result, hash)
                        }
@@ -68,8 +79,15 @@ func Download(file, checksum string) error {
                fmt.Printf("%s\r", progress.Text)
        }
 
-       _, err = lxd.DownloadFileSha256(&client, "", progress, nil, imagePath,
-               file, hash, image)
+       if sha.Size() == 32 {
+               _, err = lxd.DownloadFileSha256(&client, "", progress, nil, 
imagePath,
+                       file, hash, image)
+       } else if sha.Size() == 64 {
+               _, err = lxd.DownloadFileSha512(&client, "", progress, nil, 
imagePath,
+                       file, hash, image)
+       } else {
+               return fmt.Errorf("Cannot handle sha%d", sha.Size()*8)
+       }
        if err != nil {
                if checksum == "" && strings.HasPrefix(err.Error(), "Hash 
mismatch") {
                        return nil
diff --git a/sources/alpine-http.go b/sources/alpine-http.go
index 5be670b..6435bdc 100644
--- a/sources/alpine-http.go
+++ b/sources/alpine-http.go
@@ -38,14 +38,14 @@ func (s *AlpineLinuxHTTP) Run(definition shared.Definition, 
rootfsDir string) er
                return errors.New("GPG keys are required if downloading from 
HTTP")
        }
 
-       err = shared.Download(tarball, tarball+".sha256")
+       err = shared.DownloadSha256(tarball, tarball+".sha256")
        if err != nil {
                return err
        }
 
        // Force gpg checks when using http
        if url.Scheme != "https" {
-               shared.Download(tarball+".asc", "")
+               shared.DownloadSha256(tarball+".asc", "")
                valid, err := shared.VerifyFile(
                        filepath.Join(os.TempDir(), fname),
                        filepath.Join(os.TempDir(), fname+".asc"),
diff --git a/sources/archlinux-http.go b/sources/archlinux-http.go
index 6ca7d51..13b62c0 100644
--- a/sources/archlinux-http.go
+++ b/sources/archlinux-http.go
@@ -37,14 +37,14 @@ func (s *ArchLinuxHTTP) Run(definition shared.Definition, 
rootfsDir string) erro
                return errors.New("GPG keys are required if downloading from 
HTTP")
        }
 
-       err = shared.Download(tarball, "")
+       err = shared.DownloadSha256(tarball, "")
        if err != nil {
                return err
        }
 
        // Force gpg checks when using http
        if url.Scheme != "https" {
-               shared.Download(tarball+".sig", "")
+               shared.DownloadSha256(tarball+".sig", "")
 
                valid, err := shared.VerifyFile(
                        filepath.Join(os.TempDir(), fname),
diff --git a/sources/centos-http.go b/sources/centos-http.go
index f94f28e..e265fcd 100644
--- a/sources/centos-http.go
+++ b/sources/centos-http.go
@@ -51,7 +51,7 @@ func (s *CentOSHTTP) Run(definition shared.Definition, 
rootfsDir string) error {
                }
 
                checksumFile = "sha256sum.txt.asc"
-               shared.Download(baseURL+checksumFile, "")
+               shared.DownloadSha256(baseURL+checksumFile, "")
                valid, err := shared.VerifyFile(filepath.Join(os.TempDir(), 
checksumFile), "",
                        definition.Source.Keys, definition.Source.Keyserver)
                if err != nil {
@@ -62,7 +62,7 @@ func (s *CentOSHTTP) Run(definition shared.Definition, 
rootfsDir string) error {
                }
        }
 
-       err = shared.Download(baseURL+s.fname, checksumFile)
+       err = shared.DownloadSha256(baseURL+s.fname, checksumFile)
        if err != nil {
                return fmt.Errorf("Error downloading CentOS image: %s", err)
        }
diff --git a/sources/fedora-http.go b/sources/fedora-http.go
index 7e87803..673936d 100644
--- a/sources/fedora-http.go
+++ b/sources/fedora-http.go
@@ -41,7 +41,7 @@ func (s *FedoraHTTP) Run(definition shared.Definition, 
rootfsDir string) error {
                definition.Image.Release, build, 
definition.Image.ArchitectureMapped)
 
        // Download image
-       err = shared.Download(fmt.Sprintf("%s/%s/%s/images/%s",
+       err = shared.DownloadSha256(fmt.Sprintf("%s/%s/%s/images/%s",
                baseURL, definition.Image.Release, build, fname), "")
        if err != nil {
                return err
diff --git a/sources/ubuntu-http.go b/sources/ubuntu-http.go
index 1e7d71f..b875bcd 100644
--- a/sources/ubuntu-http.go
+++ b/sources/ubuntu-http.go
@@ -57,8 +57,8 @@ func (s *UbuntuHTTP) Run(definition shared.Definition, 
rootfsDir string) error {
                }
 
                checksumFile = baseURL + "SHA256SUMS"
-               shared.Download(baseURL+"SHA256SUMS.gpg", "")
-               shared.Download(checksumFile, "")
+               shared.DownloadSha256(baseURL+"SHA256SUMS.gpg", "")
+               shared.DownloadSha256(checksumFile, "")
 
                valid, err := shared.VerifyFile(
                        filepath.Join(os.TempDir(), "SHA256SUMS"),
@@ -73,7 +73,7 @@ func (s *UbuntuHTTP) Run(definition shared.Definition, 
rootfsDir string) error {
                }
        }
 
-       err = shared.Download(baseURL+s.fname, checksumFile)
+       err = shared.DownloadSha256(baseURL+s.fname, checksumFile)
        if err != nil {
                return fmt.Errorf("Error downloading Ubuntu image: %s", err)
        }

From 3a4d03ca82e6c7476b8a4a2e43eca0e4c105b4e2 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Thu, 29 Mar 2018 16:03:35 +0200
Subject: [PATCH 2/4] sources: Add Gentoo

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 shared/definition.go |   1 +
 sources/gentoo.go    | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++
 sources/source.go    |   2 +
 3 files changed, 106 insertions(+)
 create mode 100644 sources/gentoo.go

diff --git a/shared/definition.go b/shared/definition.go
index 8397725..4546530 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -187,6 +187,7 @@ func (d *Definition) Validate() error {
                "centos-http",
                "debootstrap",
                "fedora-http",
+               "gentoo-http",
                "ubuntu-http",
        }
        if !shared.StringInSlice(strings.TrimSpace(d.Source.Downloader), 
validDownloaders) {
diff --git a/sources/gentoo.go b/sources/gentoo.go
new file mode 100644
index 0000000..8a85069
--- /dev/null
+++ b/sources/gentoo.go
@@ -0,0 +1,103 @@
+package sources
+
+import (
+       "errors"
+       "fmt"
+       "io/ioutil"
+       "net/http"
+       "net/url"
+       "os"
+       "path/filepath"
+       "regexp"
+
+       lxd "github.com/lxc/lxd/shared"
+
+       "github.com/lxc/distrobuilder/shared"
+)
+
+// GentooHTTP represents the Alpine Linux downloader.
+type GentooHTTP struct{}
+
+// NewGentooHTTP creates a new GentooHTTP instance.
+func NewGentooHTTP() *GentooHTTP {
+       return &GentooHTTP{}
+}
+
+// Run downloads a Gentoo stage3 tarball.
+func (s *GentooHTTP) Run(definition shared.Definition, rootfsDir string) error 
{
+       baseURL := 
fmt.Sprintf("%s/releases/%s/autobuilds/current-install-%s-minimal",
+               definition.Source.URL, definition.Image.ArchitectureMapped,
+               definition.Image.ArchitectureMapped)
+       fname, err := s.getLatestBuild(baseURL, 
definition.Image.ArchitectureMapped)
+       if err != nil {
+               return err
+       }
+
+       if fname == "" {
+               return errors.New("Failed to determine latest build")
+       }
+
+       tarball := fmt.Sprintf("%s/%s", baseURL, fname)
+
+       url, err := url.Parse(tarball)
+       if err != nil {
+               return err
+       }
+
+       if url.Scheme != "https" && len(definition.Source.Keys) == 0 {
+               return errors.New("GPG keys are required if downloading from 
HTTP")
+       }
+
+       err = shared.DownloadSha512(tarball, tarball+".DIGESTS")
+       if err != nil {
+               return err
+       }
+
+       // Force gpg checks when using http
+       if url.Scheme != "https" {
+               shared.DownloadSha512(tarball+".DIGESTS.asc", "")
+               valid, err := shared.VerifyFile(
+                       filepath.Join(os.TempDir(), fname+".DIGESTS.asc"),
+                       "",
+                       definition.Source.Keys,
+                       definition.Source.Keyserver)
+               if err != nil {
+                       return err
+               }
+               if !valid {
+                       return errors.New("Failed to verify tarball")
+               }
+       }
+
+       // Unpack
+       err = lxd.Unpack(filepath.Join(os.TempDir(), fname), rootfsDir, false, 
false)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (s *GentooHTTP) getLatestBuild(baseURL, arch string) (string, error) {
+       resp, err := http.Get(baseURL)
+       if err != nil {
+               return "", err
+       }
+       defer resp.Body.Close()
+
+       body, err := ioutil.ReadAll(resp.Body)
+       if err != nil {
+               return "", err
+       }
+
+       regex := 
regexp.MustCompile(fmt.Sprintf("stage3-%s-\\d{8}T\\d{6}Z.tar.xz", arch))
+
+       // Find all stage3 related files
+       matches := regex.FindAllString(string(body), -1)
+       if len(matches) > 1 {
+               // Take the first match since they're all the same anyway
+               return matches[0], nil
+       }
+
+       return "", nil
+}
diff --git a/sources/source.go b/sources/source.go
index e7f6c8b..d84f4fe 100644
--- a/sources/source.go
+++ b/sources/source.go
@@ -20,6 +20,8 @@ func Get(name string) Downloader {
                return NewDebootstrap()
        case "fedora-http":
                return NewFedoraHTTP()
+       case "gentoo-http":
+               return NewGentooHTTP()
        case "ubuntu-http":
                return NewUbuntuHTTP()
        }

From d4e0bd1bf09ebf6da710b631204dbdf42b09e9c6 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 3 Apr 2018 15:27:37 +0200
Subject: [PATCH 3/4] managers: Add portage

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 managers/manager.go  |  2 ++
 managers/portage.go  | 24 ++++++++++++++++++++++++
 shared/definition.go |  1 +
 3 files changed, 27 insertions(+)
 create mode 100644 managers/portage.go

diff --git a/managers/manager.go b/managers/manager.go
index 1c6e7af..17ebacf 100644
--- a/managers/manager.go
+++ b/managers/manager.go
@@ -35,6 +35,8 @@ func Get(name string) *Manager {
                return NewDnf()
        case "pacman":
                return NewPacman()
+       case "portage":
+               return NewPortage()
        case "yum":
                return NewYum()
        }
diff --git a/managers/portage.go b/managers/portage.go
new file mode 100644
index 0000000..dd12dbb
--- /dev/null
+++ b/managers/portage.go
@@ -0,0 +1,24 @@
+package managers
+
+// NewPortage creates a new Manager instance.
+func NewPortage() *Manager {
+       return &Manager{
+               command: "emerge",
+               flags: ManagerFlags{
+                       global: []string{},
+                       clean:  []string{},
+                       install: []string{
+                               "--autounmask-continue",
+                       },
+                       remove: []string{
+                               "--unmerge",
+                       },
+                       refresh: []string{
+                               "--sync",
+                       },
+                       update: []string{
+                               "--update", "@world",
+                       },
+               },
+       }
+}
diff --git a/shared/definition.go b/shared/definition.go
index 4546530..9a34938 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -199,6 +199,7 @@ func (d *Definition) Validate() error {
                "apt",
                "dnf",
                "pacman",
+               "portage",
                "yum",
        }
        if !shared.StringInSlice(strings.TrimSpace(d.Packages.Manager), 
validManagers) {

From f89b0306a89efdc617ce7b46a591f7689a10e61c Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 3 Apr 2018 16:40:36 +0200
Subject: [PATCH 4/4] doc: Add gentoo example

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 doc/examples/gentoo | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 doc/examples/gentoo

diff --git a/doc/examples/gentoo b/doc/examples/gentoo
new file mode 100644
index 0000000..67ac247
--- /dev/null
+++ b/doc/examples/gentoo
@@ -0,0 +1,64 @@
+image:
+  distribution: gentoo
+  description: Gentoo
+  expiry: 30d
+  architecture: amd64
+
+source:
+  downloader: gentoo-http
+  url: http://distfiles.gentoo.org
+  keys:
+    - 13EBBDBEDE7A12775DFDB1BABB572E0E2D182910
+
+targets:
+  lxc:
+    create-message: |
+      You just created a Gentoo container (arch={{ image.architecture }})
+
+    config:
+      - type: all
+        before: 5
+        content: |-
+          lxc.include = LXC_TEMPLATE_CONFIG/alpine.common.conf
+
+      - type: user
+        before: 5
+        content: |-
+          lxc.include = LXC_TEMPLATE_CONFIG/alpine.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: portage
+
+  update: true
+  install:
+    - neovim
+
+actions:
+  - trigger: post-packages
+    action: |-
+      #!/bin/sh
+      rm -rf /usr/portage/
+
+mappings:
+  architecture_map: debian
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to