2018-02-02 17:36:48 +01:00
|
|
|
package sources
|
|
|
|
|
|
|
|
|
|
import (
|
2019-06-17 15:02:40 -04:00
|
|
|
"fmt"
|
2018-02-02 17:36:48 +01:00
|
|
|
"os"
|
2018-03-06 14:36:52 +01:00
|
|
|
"path"
|
2018-02-02 17:36:48 +01:00
|
|
|
"path/filepath"
|
2024-06-28 00:06:14 -04:00
|
|
|
"slices"
|
2018-03-14 21:26:50 -04:00
|
|
|
"strings"
|
2018-02-02 17:36:48 +01:00
|
|
|
|
2024-04-06 23:40:17 -04:00
|
|
|
incus "github.com/lxc/incus/v6/shared/util"
|
2018-05-17 22:34:04 -04:00
|
|
|
|
2018-02-02 17:36:48 +01:00
|
|
|
"github.com/lxc/distrobuilder/shared"
|
|
|
|
|
)
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
type debootstrap struct {
|
|
|
|
|
common
|
2018-02-02 17:36:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Run runs debootstrap.
|
2021-06-10 11:11:15 +02:00
|
|
|
func (s *debootstrap) Run() error {
|
2018-02-02 17:36:48 +01:00
|
|
|
var args []string
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
os.RemoveAll(s.rootfsDir)
|
2018-02-02 17:36:48 +01:00
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
if s.definition.Source.Variant != "" {
|
|
|
|
|
args = append(args, "--variant", s.definition.Source.Variant)
|
2018-02-02 17:36:48 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
if s.definition.Image.ArchitectureMapped != "" {
|
|
|
|
|
args = append(args, "--arch", s.definition.Image.ArchitectureMapped)
|
2018-02-02 17:36:48 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
if s.definition.Source.SkipVerification {
|
2018-07-02 17:37:31 +02:00
|
|
|
args = append(args, "--no-check-gpg")
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 00:06:14 -04:00
|
|
|
if s.definition.Image.Distribution == "devuan" && slices.Contains([]string{"beowulf", "chimaera"}, s.definition.Image.Release) {
|
|
|
|
|
// Workaround for debootstrap attempting to fetch non-existent usr-is-merged.
|
|
|
|
|
args = append(args, "--exclude=usr-is-merged")
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
earlyPackagesInstall := s.definition.GetEarlyPackages("install")
|
|
|
|
|
earlyPackagesRemove := s.definition.GetEarlyPackages("remove")
|
2019-10-14 16:24:46 +02:00
|
|
|
|
|
|
|
|
if len(earlyPackagesInstall) > 0 {
|
|
|
|
|
args = append(args, fmt.Sprintf("--include=%s", strings.Join(earlyPackagesInstall, ",")))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(earlyPackagesRemove) > 0 {
|
|
|
|
|
args = append(args, fmt.Sprintf("--exclude=%s", strings.Join(earlyPackagesRemove, ",")))
|
2019-06-03 12:52:32 -07:00
|
|
|
}
|
|
|
|
|
|
2023-06-28 19:28:44 +03:00
|
|
|
if len(s.definition.Source.Components) > 0 {
|
|
|
|
|
args = append(args, fmt.Sprintf("--components=%s", strings.Join(s.definition.Source.Components, ",")))
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
if len(s.definition.Source.Keys) > 0 {
|
2021-10-28 12:37:33 +02:00
|
|
|
keyring, err := s.CreateGPGKeyring()
|
2018-02-28 15:07:49 +01:00
|
|
|
if err != nil {
|
2021-09-03 09:19:03 +02:00
|
|
|
return fmt.Errorf("Failed to create GPG keyring: %w", err)
|
2018-02-28 15:07:49 +01:00
|
|
|
}
|
2023-04-21 11:22:45 +02:00
|
|
|
|
2018-03-09 09:09:22 +01:00
|
|
|
defer os.RemoveAll(path.Dir(keyring))
|
2018-02-28 15:07:49 +01:00
|
|
|
|
2018-03-06 14:36:52 +01:00
|
|
|
args = append(args, "--keyring", keyring)
|
2018-02-28 15:07:49 +01:00
|
|
|
}
|
|
|
|
|
|
2019-08-26 14:23:48 +02:00
|
|
|
// If source.suite is set, debootstrap will use this instead of
|
|
|
|
|
// image.release as its first positional argument (SUITE). This is important
|
|
|
|
|
// for derivatives which don't have their own sources, e.g. Linux Mint.
|
2021-06-10 11:11:15 +02:00
|
|
|
if s.definition.Source.Suite != "" {
|
|
|
|
|
args = append(args, s.definition.Source.Suite, s.rootfsDir)
|
2018-05-09 12:29:44 +02:00
|
|
|
} else {
|
2021-06-10 11:11:15 +02:00
|
|
|
args = append(args, s.definition.Image.Release, s.rootfsDir)
|
2018-05-09 12:29:44 +02:00
|
|
|
}
|
2018-02-02 17:36:48 +01:00
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
if s.definition.Source.URL != "" {
|
|
|
|
|
args = append(args, s.definition.Source.URL)
|
2018-02-02 17:36:48 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-10 11:11:15 +02:00
|
|
|
// If s.definition.Source.SameAs is set, create a symlink in /usr/share/debootstrap/scripts
|
|
|
|
|
// pointing release to s.definition.Source.SameAs.
|
|
|
|
|
scriptPath := filepath.Join("/usr/share/debootstrap/scripts", s.definition.Image.Release)
|
2023-09-05 16:45:26 -04:00
|
|
|
if !incus.PathExists(scriptPath) && s.definition.Source.SameAs != "" {
|
2021-06-10 11:11:15 +02:00
|
|
|
err := os.Symlink(s.definition.Source.SameAs, scriptPath)
|
2018-03-01 09:05:32 +01:00
|
|
|
if err != nil {
|
2021-09-03 09:19:03 +02:00
|
|
|
return fmt.Errorf("Failed to create symlink: %w", err)
|
2018-03-01 09:05:32 +01:00
|
|
|
}
|
2018-05-17 22:34:04 -04:00
|
|
|
|
|
|
|
|
defer os.Remove(scriptPath)
|
2018-03-01 09:05:32 +01:00
|
|
|
}
|
|
|
|
|
|
2021-11-17 16:15:59 +01:00
|
|
|
err := shared.RunCommand(s.ctx, nil, nil, "debootstrap", args...)
|
2021-06-21 14:12:46 +02:00
|
|
|
if err != nil {
|
2021-09-03 09:19:03 +02:00
|
|
|
return fmt.Errorf(`Failed to run "debootstrap": %w`, err)
|
2021-06-21 14:12:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
2018-02-02 17:36:48 +01:00
|
|
|
}
|