Skip to content

Commit deb2d1f

Browse files
invidiancpuguy83
authored andcommitted
targets/linux/deb/distro/container.go: refactor for bootstrapped containers
Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>
1 parent 9d56e02 commit deb2d1f

2 files changed

Lines changed: 116 additions & 66 deletions

File tree

targets/linux/deb/distro/container.go

Lines changed: 107 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,81 +13,126 @@ import (
1313
func (c *Config) BuildContainer(ctx context.Context, client gwclient.Client, sOpt dalec.SourceOpts, spec *dalec.Spec, targetKey string, debSt llb.State, opts ...llb.ConstraintsOpt) llb.State {
1414
opts = append(opts, frontend.IgnoreCache(client), dalec.ProgressGroup("Build Container Image"))
1515

16-
baseImg := llb.Image(c.DefaultOutputImage, llb.WithMetaResolver(sOpt.Resolver), dalec.WithConstraints(opts...))
17-
18-
bi, err := spec.GetSingleBase(targetKey)
19-
if err != nil {
20-
return dalec.ErrorState(llb.Scratch(), err)
21-
}
22-
23-
if bi != nil {
24-
baseImg = bi.ToState(sOpt, opts...)
16+
input := buildContainerInput{
17+
Config: c,
18+
Client: client,
19+
Worker: c.Worker(sOpt, dalec.Platform(sOpt.TargetPlatform), dalec.WithConstraints(opts...)),
20+
SOpt: sOpt,
21+
Spec: spec,
22+
Target: targetKey,
23+
SpecPackages: debSt,
24+
Opts: opts,
2525
}
2626

27-
// Those base repos come from distro configuration.
28-
repos := dalec.GetExtraRepos(c.ExtraRepos, "install")
29-
30-
// These are user specified via spec.
31-
repos = append(repos, spec.GetInstallRepos(targetKey)...)
32-
33-
withRepos := c.RepoMounts(repos, sOpt, opts...)
34-
35-
debug := llb.Scratch().File(llb.Mkfile("debug", 0o644, []byte(`debug=2`)), opts...)
36-
opts = append(opts, dalec.ProgressGroup("Install spec package"))
27+
baseImg := baseImageFromSpec(llb.Image(c.DefaultOutputImage, llb.WithMetaResolver(sOpt.Resolver), dalec.WithConstraints(opts...)), input)
3728

38-
// If we have base packages to install, create a meta-package to install them.
3929
if len(c.BasePackages) > 0 {
40-
runtimePkgs := make(dalec.PackageDependencyList, len(c.BasePackages))
41-
for _, pkgName := range c.BasePackages {
42-
runtimePkgs[pkgName] = dalec.PackageConstraints{}
43-
}
44-
basePkgSpec := &dalec.Spec{
45-
Name: "dalec-deb-base-packages",
46-
Packager: "dalec",
47-
Description: "Base Packages for Debian-based Distros",
48-
Version: "0.1",
49-
Revision: "1",
50-
Dependencies: &dalec.PackageDependencies{
51-
Runtime: runtimePkgs,
52-
},
53-
}
54-
55-
basePkg := c.BuildPkg(ctx, client, sOpt, basePkgSpec, targetKey, opts...)
30+
opts = append(opts, dalec.ProgressGroup("Install base image packages"))
5631

5732
// Update the base image to include the base packages.
5833
// This may include things that are necessary to even install the debSt package.
5934
// So this must be done separately from the debSt package.
60-
opts := append(opts, dalec.ProgressGroup("Install base image packages"))
6135
baseImg = baseImg.Run(
6236
dalec.WithConstraints(opts...),
63-
InstallLocalPkg(basePkg, true, opts...),
37+
InstallLocalPkg(basePackages(ctx, input), true, opts...),
6438
dalec.WithMountedAptCache(c.AptCachePrefix, opts...),
6539
).Root()
6640
}
6741

68-
worker := c.Worker(sOpt, dalec.Platform(sOpt.TargetPlatform), dalec.WithConstraints(opts...))
69-
70-
return baseImg.Run(
71-
dalec.WithConstraints(opts...),
72-
withRepos,
73-
dalec.WithMountedAptCache(c.AptCachePrefix, opts...),
74-
// This file makes dpkg give more verbose output which can be useful when things go awry.
75-
llb.AddMount("/etc/dpkg/dpkg.cfg.d/99-dalec-debug", debug, llb.SourcePath("debug"), llb.Readonly),
76-
dalec.RunOptFunc(func(cfg *llb.ExecInfo) {
77-
// Warning: HACK here
78-
// The base ubuntu image has this `excludes` config file which prevents
79-
// installation of a lot of things, including doc files.
80-
// This is mounting over that file with an empty file so that our test suite
81-
// passes (as it is looking at these files).
82-
if !spec.GetArtifacts(targetKey).HasDocs() {
83-
return
84-
}
85-
86-
tmp := llb.Scratch().File(llb.Mkfile("tmp", 0o644, nil), opts...)
87-
llb.AddMount("/etc/dpkg/dpkg.cfg.d/excludes", tmp, llb.SourcePath("tmp")).SetRunOption(cfg)
88-
}),
42+
return baseImg.With(installPackagesInContainer(input, []llb.RunOption{
43+
dalec.WithMountedAptCache(input.Config.AptCachePrefix, opts...),
8944
InstallLocalPkg(debSt, true, opts...),
90-
frontend.IgnoreCache(client, targets.IgnoreCacheKeyContainer),
91-
).Root().
92-
With(dalec.InstallPostSymlinks(spec.GetImagePost(targetKey), worker, opts...))
45+
}))
46+
}
47+
48+
func baseImageFromSpec(baseImg llb.State, input buildContainerInput) llb.State {
49+
bi, err := input.Spec.GetSingleBase(input.Target)
50+
if err != nil {
51+
return dalec.ErrorState(llb.Scratch(), err)
52+
}
53+
54+
if bi == nil {
55+
return baseImg
56+
}
57+
58+
return bi.ToState(input.SOpt, input.Opts...)
59+
}
60+
61+
func basePackages(ctx context.Context, input buildContainerInput) llb.State {
62+
if len(input.Config.BasePackages) == 0 {
63+
return llb.Scratch()
64+
}
65+
66+
// If we have base packages to install, create a meta-package to install them.
67+
runtimePkgs := make(dalec.PackageDependencyList, len(input.Config.BasePackages))
68+
for _, pkgName := range input.Config.BasePackages {
69+
runtimePkgs[pkgName] = dalec.PackageConstraints{}
70+
}
71+
basePkgSpec := &dalec.Spec{
72+
Name: "dalec-deb-base-packages",
73+
Packager: "dalec",
74+
Description: "Base Packages for Debian-based Distros",
75+
Version: "0.1",
76+
Revision: "1",
77+
Dependencies: &dalec.PackageDependencies{
78+
Runtime: runtimePkgs,
79+
},
80+
}
81+
82+
opts := append(input.Opts, dalec.ProgressGroup("Install base image packages"))
83+
84+
return input.Config.BuildPkg(ctx, input.Client, input.SOpt, basePkgSpec, input.Target, opts...)
85+
}
86+
87+
type buildContainerInput struct {
88+
Config *Config
89+
Client gwclient.Client
90+
Worker llb.State
91+
SOpt dalec.SourceOpts
92+
Spec *dalec.Spec
93+
Target string
94+
SpecPackages llb.State
95+
Opts []llb.ConstraintsOpt
96+
}
97+
98+
func extraRepos(input buildContainerInput) llb.RunOption {
99+
// Those base repos come from distro configuration.
100+
repos := dalec.GetExtraRepos(input.Config.ExtraRepos, "install")
101+
102+
// These are user specified via spec.
103+
repos = append(repos, input.Spec.GetInstallRepos(input.Target)...)
104+
105+
return input.Config.RepoMounts(repos, input.SOpt, input.Opts...)
106+
}
107+
108+
func installPackagesInContainer(input buildContainerInput, ro []llb.RunOption) llb.StateOption {
109+
return func(baseImg llb.State) llb.State {
110+
opts := append(input.Opts, dalec.ProgressGroup("Install spec package"))
111+
112+
debug := llb.Scratch().File(llb.Mkfile("debug", 0o644, []byte(`debug=2`)), opts...)
113+
114+
return baseImg.Run(
115+
append(ro,
116+
dalec.WithConstraints(opts...),
117+
extraRepos(input),
118+
// This file makes dpkg give more verbose output which can be useful when things go awry.
119+
llb.AddMount("/etc/dpkg/dpkg.cfg.d/99-dalec-debug", debug, llb.SourcePath("debug"), llb.Readonly),
120+
dalec.RunOptFunc(func(cfg *llb.ExecInfo) {
121+
// Warning: HACK here
122+
// The base ubuntu image has this `excludes` config file which prevents
123+
// installation of a lot of things, including doc files.
124+
// This is mounting over that file with an empty file so that our test suite
125+
// passes (as it is looking at these files).
126+
if !input.Spec.GetArtifacts(input.Target).HasDocs() {
127+
return
128+
}
129+
130+
tmp := llb.Scratch().File(llb.Mkfile("tmp", 0o644, nil), opts...)
131+
llb.AddMount("/etc/dpkg/dpkg.cfg.d/excludes", tmp, llb.SourcePath("tmp")).SetRunOption(cfg)
132+
}),
133+
frontend.IgnoreCache(input.Client, targets.IgnoreCacheKeyContainer),
134+
)...,
135+
).Root().
136+
With(dalec.InstallPostSymlinks(input.Spec.GetImagePost(input.Target), input.Worker, opts...))
137+
}
93138
}

test/linux_target_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -925,12 +925,12 @@ index 0000000..5260cb1
925925
t.Fatalf("Unexpected error extracting LLB OPs from state: %v", err)
926926
}
927927

928-
cacheIgnored := 0
928+
cacheIgnored := []test.LLBOp{}
929929
execFound := false
930930

931931
for _, op := range ops {
932932
if op.OpMetadata.IgnoreCache {
933-
cacheIgnored++
933+
cacheIgnored = append(cacheIgnored, op)
934934
}
935935

936936
e := op.Op.GetExec()
@@ -950,8 +950,13 @@ index 0000000..5260cb1
950950
t.Errorf("No exec ops found in the build")
951951
}
952952

953-
if cacheIgnored > 1 {
954-
t.Fatalf("Expected only one operation to have cache ignore enabled, found %d", cacheIgnored)
953+
if len(cacheIgnored) > 1 {
954+
ops, err := test.LLBOpsToJSON(cacheIgnored)
955+
if err != nil {
956+
t.Errorf("Error converting ops to JSON: %v", err)
957+
}
958+
959+
t.Errorf("Expected only one operation to have cache ignore enabled, found %d: \n%s", len(cacheIgnored), ops)
955960
}
956961
})
957962
})

0 commit comments

Comments
 (0)