Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

actions: Add mmdebstrap action #515

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ jobs:
- { name: "partitioning", case: "partitioning" }
- { name: "msdos partitioning", case: "msdos" }
- { name: "debian (amd64)", case: "debian", variables: "-t architecture:amd64" }
- { name: "debian with mmdebstrap (amd64)", case: "debian", variables: "-t architecture:amd64 -t tool:mmdebstrap" }
exclude:
- backend: nofakemachine
test: { name: "partitioning", case: "partitioning" }
Expand Down
184 changes: 184 additions & 0 deletions actions/mmdebstrap_action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
mmdebstrap Action

Construct the target rootfs with mmdebstrap tool.

Please keep in mind -- file `/etc/resolv.conf` will be removed after execution.
Most of the OS scripts used by `mmdebstrap` copy `resolv.conf` from the host,
and this may lead to incorrect configuration when becoming part of the created rootfs.

# Yaml syntax:
- action: mmdebstrap
mirrors: <list of URLs>
suite: "name"
components: <list of components>
variant: "name"
keyring-packages:
keyring-files:

Mandatory properties:

- suite -- release code name or symbolic name (e.g. "stable")

Optional properties:

- mirrors -- list of URLs with Debian-compatible repository
If no mirror is specified debos will use http://deb.debian.org/debian as default.

- variant -- name of the bootstrap script variant to use

- components -- list of components to use for packages selection.
If no components are specified debos will use main as default.

Example:
components: [ main, contrib ]

- keyring-packages -- list of keyrings for package validation.

- keyring-files -- list keyring files for repository validation.

- merged-usr -- use merged '/usr' filesystem, true by default.

*/
package actions

import (
"fmt"
"os"
"path"
"strings"
"runtime"

"github.com/go-debos/debos"
"github.com/go-debos/fakemachine"
)

type MmdebstrapAction struct {
debos.BaseAction `yaml:",inline"`
Suite string
Mirrors []string
Variant string
KeyringPackages []string `yaml:"keyring-packages"`
KeyringFiles []string `yaml:"keyring-files"`
Components []string
MergedUsr *bool `yaml:"merged-usr"`
}

func NewMmdebstrapAction() *MmdebstrapAction {
d := MmdebstrapAction{}
// Be secure by default
// Use main as default component
d.Components = []string{"main"}

return &d
}

func (d *MmdebstrapAction) listOptionFiles(context *debos.DebosContext) []string {
files := []string{}

if d.KeyringFiles != nil {
for _, file := range d.KeyringFiles {
file = debos.CleanPathAt(file, context.RecipeDir)
files = append(files, file)
}
}

return files
}

func (d *MmdebstrapAction) Verify(context *debos.DebosContext) error {
if len(d.Suite) == 0 {
return fmt.Errorf("suite property not specified")
}

files := d.listOptionFiles(context)

// Check if all needed files exists
for _, f := range files {
if _, err := os.Stat(f); os.IsNotExist(err) {
return err
}
}
return nil
}

func (d *MmdebstrapAction) PreMachine(context *debos.DebosContext, m *fakemachine.Machine, args *[]string) error {

mounts := d.listOptionFiles(context)

// Mount configuration files outside of recipes directory
for _, mount := range mounts {
m.AddVolume(path.Dir(mount))
}

return nil
}

func (d *MmdebstrapAction) Run(context *debos.DebosContext) error {
cmdline := []string{"mmdebstrap"}

if d.MergedUsr != nil {
if *d.MergedUsr {
cmdline = append(cmdline, "--include=usrmerge")
} else {
cmdline = append(cmdline, "--hook-dir=/usr/share/mmdebstrap/hooks/no-merged-usr")
}
}

if d.KeyringFiles != nil {
s := strings.Join(d.KeyringFiles, ",")
cmdline = append(cmdline, fmt.Sprintf("--keyring=%s", s))
}

if d.KeyringPackages != nil {
s := strings.Join(d.KeyringPackages, ",")
cmdline = append(cmdline, fmt.Sprintf("--include=%s", s))
}

if d.Components != nil {
s := strings.Join(d.Components, ",")
cmdline = append(cmdline, fmt.Sprintf("--components=%s", s))
}

/* Only works for amd64, arm64 and riscv64 hosts, which should be enough */
foreign := context.Architecture != runtime.GOARCH

if foreign {
cmdline = append(cmdline, fmt.Sprintf("--architectures=%s", context.Architecture))

}

if d.Variant != "" {
cmdline = append(cmdline, fmt.Sprintf("--variant=%s", d.Variant))
}

cmdline = append(cmdline, d.Suite)
cmdline = append(cmdline, context.Rootdir)

if d.Mirrors != nil {
cmdline = append(cmdline, d.Mirrors...)
}

/* Make sure files in /etc/apt/ exist inside the fakemachine otherwise
mmdebstrap prints a warning about the path not existing. */
if fakemachine.InMachine() {
if err := os.MkdirAll(path.Join("/etc/apt/apt.conf.d"), os.ModePerm); err != nil {
return err
}
if err := os.MkdirAll(path.Join("/etc/apt/trusted.gpg.d"), os.ModePerm); err != nil {
return err
}
}

err := debos.Command{}.Run("Mmdebstrap", cmdline...)

/* Cleanup resolv.conf after mmdebstrap */
resolvconf := path.Join(context.Rootdir, "/etc/resolv.conf")
if _, err = os.Stat(resolvconf); !os.IsNotExist(err) {
if err = os.Remove(resolvconf); err != nil {
return err
}
}

return err
}
4 changes: 4 additions & 0 deletions actions/recipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Supported actions

- debootstrap -- https://godoc.org/github.com/go-debos/debos/actions#hdr-Debootstrap_Action

- mmdebstrap -- https://godoc.org/github.com/go-debos/debos/actions#hdr-Mmdebstrap_Action

- download -- https://godoc.org/github.com/go-debos/debos/actions#hdr-Download_Action

- filesystem-deploy -- https://godoc.org/github.com/go-debos/debos/actions#hdr-FilesystemDeploy_Action
Expand Down Expand Up @@ -115,6 +117,8 @@ func (y *YamlAction) UnmarshalYAML(unmarshal func(interface{}) error) error {
switch aux.Action {
case "debootstrap":
y.Action = NewDebootstrapAction()
case "mmdebstrap":
y.Action = NewMmdebstrapAction()
case "pacstrap":
y.Action = &PacstrapAction{}
case "pack":
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ RUN apt-get update && \
ca-certificates \
debian-ports-archive-keyring \
debootstrap \
mmdebstrap \
dosfstools \
e2fsprogs \
equivs \
Expand Down
3 changes: 2 additions & 1 deletion tests/debian/test.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
{{- $architecture := or .architecture "amd64"}}
{{- $tool := or .tool "debootstrap" }}
architecture: {{$architecture}}

actions:
- action: debootstrap
- action: {{ $tool }}
suite: bullseye
variant: minbase
merged-usr: true
Expand Down