diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d0d9cdee..9fbe02e9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -125,9 +125,12 @@ jobs: test: - { name: "recipes", case: "recipes" } - { name: "templating", case: "templating", variables: " -t escaped:\\$ba\\'d\\$gers\\ snakes" } - - { name: "debian (amd64)", case: "debian", variables: "-t architecture:amd64" } - - { name: "debian (arm64)", case: "debian", variables: "-t architecture:arm64" } - - { name: "debian (armhf)", case: "debian", variables: "-t architecture:armhf" } + - { name: "debian (bookworm amd64)", case: "debian", variables: "-t architecture:amd64 -t suite:bookworm" } + - { name: "debian (bookworm arm64)", case: "debian", variables: "-t architecture:arm64 -t suite:bookworm" } + - { name: "debian (bookworm armhf)", case: "debian", variables: "-t architecture:armhf -t suite:bookworm" } + - { name: "debian (trixie amd64)", case: "debian", variables: "-t architecture:amd64 -t suite:trixie" } + - { name: "debian (trixie arm64)", case: "debian", variables: "-t architecture:arm64 -t suite:trixie" } + - { name: "debian (trixie armhf)", case: "debian", variables: "-t architecture:armhf -t suite:trixie" } exclude: - backend: nofakemachine test: { name: "partitioning", case: "partitioning" } @@ -136,6 +139,12 @@ jobs: test: { name: "arch", case: "arch" } - backend: kvm test: { name: "apertis", case: "apertis" } + - backend: kvm + test: { name: "kali", case: "kali" } + - backend: kvm + test: { name: "apertis v2022", case: "apertis", variables: "-t suite:v2022" } + - backend: kvm + test: { name: "apertis v2024dev3", case: "apertis", variables: "-t suite:v2024dev3 -t parent_suite:bookworm" } name: ${{matrix.test.name}} on ${{matrix.backend}} runs-on: ${{ matrix.backend == 'kvm' && 'kvm' || 'ubuntu-latest' }} steps: diff --git a/actions/debootstrap_action.go b/actions/debootstrap_action.go index ac42aa7a..4b9d3b72 100644 --- a/actions/debootstrap_action.go +++ b/actions/debootstrap_action.go @@ -46,10 +46,19 @@ Example: - certificate -- client certificate stored in file to be used for downloading packages from the server. - private-key -- provide the client's private key in a file separate from the certificate. + +- parent-suite -- release code name which this suite is based on. Useful for downstreams which do + not use debian codenames for their suite names (e.g. "stable"). + +- script -- the full path of the script to use to build the target rootfs. (e.g. `/usr/share/debootstrap/scripts/kali`) + If unspecified, the property will be automatically determined in the following order, + with the path "/usr/share/debootstrap/scripts/" prepended: + `suite` property, `parent-suite` property then `unstable`. */ package actions import ( + "errors" "fmt" "io" "log" @@ -64,6 +73,7 @@ import ( type DebootstrapAction struct { debos.BaseAction `yaml:",inline"` + ParentSuite string `yaml:"parent-suite"` Suite string Mirror string Variant string @@ -74,6 +84,7 @@ type DebootstrapAction struct { Components []string MergedUsr bool `yaml:"merged-usr"` CheckGpg bool `yaml:"check-gpg"` + Script string } func NewDebootstrapAction() *DebootstrapAction { @@ -115,6 +126,10 @@ func (d *DebootstrapAction) Verify(context *debos.DebosContext) error { return fmt.Errorf("suite property not specified") } + if len(d.ParentSuite) == 0 { + d.ParentSuite = d.Suite + } + files := d.listOptionFiles(context) // Check if all needed files exists @@ -163,9 +178,9 @@ func (d *DebootstrapAction) RunSecondStage(context debos.DebosContext) error { return err } -// Guess if suite is something before usr-is-merged was introduced -func (d *DebootstrapAction) isLikelyOldSuite() bool { - switch strings.ToLower(d.Suite) { +// Check if suite is something before usr-is-merged was introduced +func shouldExcludeUsrIsMerged(suite string) bool { + switch strings.ToLower(suite) { case "sid", "unstable": return false case "testing": @@ -181,6 +196,10 @@ func (d *DebootstrapAction) isLikelyOldSuite() bool { } } +func getDebootstrapScriptPath(script string) string { + return path.Join("/usr/share/debootstrap/scripts/", script) +} + func (d *DebootstrapAction) Run(context *debos.DebosContext) error { cmdline := []string{"debootstrap"} @@ -226,16 +245,41 @@ func (d *DebootstrapAction) Run(context *debos.DebosContext) error { cmdline = append(cmdline, fmt.Sprintf("--variant=%s", d.Variant)) } - // workaround for https://github.com/go-debos/debos/issues/361 - if d.isLikelyOldSuite() { - log.Println("excluding usr-is-merged as package is not in suite") + if shouldExcludeUsrIsMerged(d.ParentSuite) { + log.Printf("excluding usr-is-merged as package is not in parent suite %s\n", d.ParentSuite) cmdline = append(cmdline, "--exclude=usr-is-merged") } cmdline = append(cmdline, d.Suite) cmdline = append(cmdline, context.Rootdir) cmdline = append(cmdline, d.Mirror) - cmdline = append(cmdline, "/usr/share/debootstrap/scripts/unstable") + + if len(d.Script) > 0 { + if _, err := os.Stat(d.Script); err != nil { + return fmt.Errorf("cannot find debootstrap script %s", d.Script) + } + } else { + /* Auto determine debootstrap script to use from d.Suite, falling back to + d.ParentSuite if it doesn't exist. Finally, fallback to unstable if a + script for the parent suite does not exist. */ + for _, s := range []string{d.Suite, d.ParentSuite, "unstable"} { + d.Script = getDebootstrapScriptPath(s) + if _, err := os.Stat(d.Script); err == nil { + break + } else { + log.Printf("cannot find debootstrap script %s\n", d.Script) + + /* Unstable should always be available so error out if not */ + if s == "unstable" { + return errors.New("cannot find debootstrap script for unstable") + } + } + } + + log.Printf("using debootstrap script %s\n", d.Script) + } + + cmdline = append(cmdline, d.Script) /* Make sure /etc/apt/apt.conf.d exists inside the fakemachine otherwise debootstrap prints a warning about the path not existing. */ diff --git a/tests/apertis/test.yaml b/tests/apertis/test.yaml index 4cde8606..62040447 100644 --- a/tests/apertis/test.yaml +++ b/tests/apertis/test.yaml @@ -1,12 +1,17 @@ --- # Test building a non-debian distribution such as apertis to ensure # bootstrapping suites that debootstrap won't internally know about works -{{- $architecture := or .architecture "amd64"}} -architecture: {{$architecture}} + +{{- $architecture := or .architecture "amd64" }} +{{- $suite := or .suite "v2022" }} +{{- $parent_suite := or .parent_suite "" }} + +architecture: {{ $architecture }} actions: - action: debootstrap - suite: v2022 + suite: {{ $suite }} + parent-suite: {{ $parent_suite }} components: - target mirror: https://repositories.apertis.org/apertis/ diff --git a/tests/debian/test.yaml b/tests/debian/test.yaml index bf4adb2a..d53316a2 100644 --- a/tests/debian/test.yaml +++ b/tests/debian/test.yaml @@ -1,10 +1,12 @@ --- -{{- $architecture := or .architecture "amd64"}} -architecture: {{$architecture}} +{{- $architecture := or .architecture "amd64" }} +{{- $suite := or .suite "bookworm" }} + +architecture: {{ $architecture }} actions: - action: debootstrap - suite: bullseye + suite: {{ $suite }} variant: minbase merged-usr: true diff --git a/tests/kali/kali-archive-keyring.gpg b/tests/kali/kali-archive-keyring.gpg new file mode 100644 index 00000000..244b2b50 Binary files /dev/null and b/tests/kali/kali-archive-keyring.gpg differ diff --git a/tests/kali/test.yaml b/tests/kali/test.yaml new file mode 100644 index 00000000..5a40306f --- /dev/null +++ b/tests/kali/test.yaml @@ -0,0 +1,23 @@ +--- +# Test building a non-debian distribution based on unstable such as kali-rolling +# to ensure bootstrapping suites that debootstrap won't internally know about +# works +{{- $architecture := or .architecture "amd64" }} + +architecture: {{ $architecture }} + +actions: + - action: debootstrap + suite: kali-rolling + parent-suite: testing + components: + - main + mirror: https://http.kali.org/kali/ + variant: minbase + keyring-package: kali-archive-keyring + keyring-file: kali-archive-keyring.gpg + + - action: apt + description: Install some base packages + packages: + - procps