@@ -13,81 +13,126 @@ import (
1313func (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}
0 commit comments