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

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) ===
I'm trying to modify the distrobuilder to work with OpenWrt. I think I understood most parts of the process, however there are some corners I haven't figured out yet:

- [x] Checksums are downloaded
- [x] Checksums are GPG verified
- [ ] Checksums are compared with the actual file. Says Checksum isn't found locally
- [x] Additional manager is added (opkg)
  - [ ] Fix failure due to missing `/var/lock/` folder

I'll continue to work on the missing bits but would be happy to get some comments if I'm on the wrong track.
From 871f29940599c7c5249278a3dd50a59ee7f7d175 Mon Sep 17 00:00:00 2001
From: Paul Spooren <[email protected]>
Date: Mon, 20 May 2019 13:07:42 +0200
Subject: [PATCH] opkg: add distro

---
 doc/examples/openwrt    | 60 ++++++++++++++++++++++++++
 managers/manager.go     |  2 +
 managers/opkg.go        | 32 ++++++++++++++
 shared/definition.go    |  2 +
 sources/openwrt-http.go | 94 +++++++++++++++++++++++++++++++++++++++++
 sources/source.go       |  2 +
 6 files changed, 192 insertions(+)
 create mode 100644 doc/examples/openwrt
 create mode 100644 managers/opkg.go
 create mode 100644 sources/openwrt-http.go

diff --git a/doc/examples/openwrt b/doc/examples/openwrt
new file mode 100644
index 0000000..1ef5648
--- /dev/null
+++ b/doc/examples/openwrt
@@ -0,0 +1,60 @@
+image:
+  distribution: OpenWrt
+  release: snapshot
+  description: OpenWrt {{ image.release }}
+  expiry: 30d
+  architecture: x86_64
+
+source:
+  downloader: openwrt-http
+  url: https://downloads.openwrt.org
+  keyserver: keyserver.ubuntu.com
+  keys:
+    - 0x6768C55E79B032D77A28DA5F0F20257417E1CE16
+    - 0x54CC74307A2C6DC9CE618269CD84BCED626471F1
+    - 0x6D9278A33A9AB3146262DCECF93525A88B699029
+
+targets:
+  lxc:
+    create-message: |
+      You just created an {{ image.distribution }} container (release={{ 
image.release }}, arch={{ image.architecture }})
+
+    config:
+      - type: all
+        before: 5
+        content: |-
+          lxc.include = LXC_TEMPLATE_CONFIG/openwrt.common.conf
+
+      - type: user
+        before: 5
+        content: |-
+          lxc.include = LXC_TEMPLATE_CONFIG/openwrt.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
+
+  - path: /tmp/lock/opkg.lock
+    generator: dump
+
+packages:
+  manager: opkg
+  update: false
+  cleanup: false
diff --git a/managers/manager.go b/managers/manager.go
index 5823052..4965e1a 100644
--- a/managers/manager.go
+++ b/managers/manager.go
@@ -43,6 +43,8 @@ func Get(name string) *Manager {
                return NewApt()
        case "dnf":
                return NewDnf()
+       case "opkg":
+               return NewOpkg()
        case "pacman":
                return NewPacman()
        case "portage":
diff --git a/managers/opkg.go b/managers/opkg.go
new file mode 100644
index 0000000..1b5aedb
--- /dev/null
+++ b/managers/opkg.go
@@ -0,0 +1,32 @@
+package managers
+
+// NewOpkg creates a new Manager instance.
+func NewOpkg() *Manager {
+       return &Manager{
+               commands: ManagerCommands{
+                       clean:   "echo",
+                       install: "echo",
+                       refresh: "opkg",
+                       remove:  "echo",
+                       update:  "echo",
+               },
+               flags: ManagerFlags{
+                       clean: []string{
+                               "",
+                       },
+                       global: []string{},
+                       install: []string{
+                               "install",
+                       },
+                       remove: []string{
+                               "remove",
+                       },
+                       refresh: []string{
+                               "update",
+                       },
+                       update: []string{
+                               "",
+                       },
+               },
+       }
+}
diff --git a/shared/definition.go b/shared/definition.go
index 5a83975..058a32b 100644
--- a/shared/definition.go
+++ b/shared/definition.go
@@ -259,6 +259,7 @@ func (d *Definition) Validate() error {
                "docker-http",
                "oraclelinux-http",
                "opensuse-http",
+               "openwrt-http",
                "plamolinux-http",
        }
        if !shared.StringInSlice(strings.TrimSpace(d.Source.Downloader), 
validDownloaders) {
@@ -270,6 +271,7 @@ func (d *Definition) Validate() error {
                        "apk",
                        "apt",
                        "dnf",
+                       "opkg",
                        "pacman",
                        "portage",
                        "yum",
diff --git a/sources/openwrt-http.go b/sources/openwrt-http.go
new file mode 100644
index 0000000..d11fef6
--- /dev/null
+++ b/sources/openwrt-http.go
@@ -0,0 +1,94 @@
+package sources
+
+import (
+       "crypto/sha256"
+       "errors"
+       "fmt"
+       "net/url"
+       "path/filepath"
+       "strings"
+
+       lxd "github.com/lxc/lxd/shared"
+
+       "github.com/lxc/distrobuilder/shared"
+)
+
+// OpenWrtHTTP represents the ALT Linux downloader.
+type OpenWrtHTTP struct{}
+
+// NewOpenWrtHTTP creates a new OpenWrtHTTP instance.
+func NewOpenWrtHTTP() *OpenWrtHTTP {
+       return &OpenWrtHTTP{}
+}
+
+// Run downloads the tarball and unpacks it.
+func (s *OpenWrtHTTP) Run(definition shared.Definition, rootfsDir string) 
error {
+       release := definition.Image.Release
+
+       architecturePath := 
strings.Replace(definition.Image.ArchitectureMapped, "_", "/", 1)
+
+       baseURL := fmt.Sprintf("%s/releases/%s/targets/%s/",
+               definition.Source.URL, release, architecturePath)
+       if release == "snapshot" {
+               baseURL = fmt.Sprintf("%s/snapshots/targets/%s/",
+                       definition.Source.URL, architecturePath)
+       }
+
+       releaseInFilename := strings.ToLower(release) + "-"
+
+       if release == "snapshot" {
+               releaseInFilename = ""
+       }
+
+       fname := fmt.Sprintf("openwrt-%s%s-generic-rootfs.tar.gz", 
releaseInFilename,
+               strings.Replace(definition.Image.ArchitectureMapped, "_", "-", 
1))
+
+       url, err := url.Parse(baseURL)
+       if err != nil {
+               return err
+       }
+
+       checksumFile := ""
+       if definition.Source.SkipVerification {
+               if len(definition.Source.Keys) != 0 {
+
+                       checksumFile = baseURL + "sha256sums"
+                       fpath, err := shared.DownloadHash(definition.Image, 
checksumFile+".asc", "", nil)
+                       if err != nil {
+                               return err
+                       }
+
+                       shared.DownloadHash(definition.Image, checksumFile, "", 
nil)
+
+                       valid, err := shared.VerifyFile(
+                               filepath.Join(fpath, "sha256sums"),
+                               filepath.Join(fpath, "sha256sums.asc"),
+                               definition.Source.Keys,
+                               definition.Source.Keyserver)
+                       if err != nil {
+                               return err
+                       }
+                       if !valid {
+                               return fmt.Errorf("Failed to validate archive")
+                       }
+               } else {
+                       // Force gpg checks when using http
+                       if url.Scheme != "https" {
+                               return errors.New("GPG keys are required if 
downloading from HTTP")
+                       }
+               }
+       }
+
+       fpath, err := shared.DownloadHash(definition.Image, baseURL+fname, 
checksumFile, sha256.New())
+       if err != nil {
+               return err
+       }
+
+       // Unpack
+       err = lxd.Unpack(filepath.Join(fpath, fname), rootfsDir, false, false, 
nil)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
diff --git a/sources/source.go b/sources/source.go
index 657bc8a..b6f9356 100644
--- a/sources/source.go
+++ b/sources/source.go
@@ -34,6 +34,8 @@ func Get(name string) Downloader {
                return NewOracleLinuxHTTP()
        case "opensuse-http":
                return NewOpenSUSEHTTP()
+       case "openwrt-http":
+               return NewOpenWrtHTTP()
        case "plamolinux-http":
                return NewPlamoLinuxHTTP()
        }
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to