@@ -24,6 +24,7 @@ import (
2424 "sigs.k8s.io/yaml"
2525
2626 operatorv1alpha1 "github.com/openshift/api/operator/v1alpha1"
27+ "github.com/openshift/installer/pkg/asset/agent"
2728 "github.com/openshift/installer/pkg/asset/agent/mirror"
2829 "github.com/openshift/installer/pkg/rhcos"
2930 "github.com/openshift/installer/pkg/rhcos/cache"
@@ -34,19 +35,19 @@ const (
3435 coreOsFileName = "/coreos/coreos-%s.iso"
3536 coreOsSha256FileName = "/coreos/coreos-%s.iso.sha256"
3637 coreOsStreamFileName = "/coreos/coreos-stream.json"
37- //OcDefaultTries is the number of times to execute the oc command on failues
38+ // OcDefaultTries is the number of times to execute the oc command on failures.
3839 OcDefaultTries = 5
39- // OcDefaultRetryDelay is the time between retries
40+ // OcDefaultRetryDelay is the time between retries.
4041 OcDefaultRetryDelay = time .Second * 5
4142)
4243
43- // Config is used to set up the retries for extracting the base ISO
44+ // Config is used to set up the retries for extracting the base ISO.
4445type Config struct {
4546 MaxTries uint
4647 RetryDelay time.Duration
4748}
4849
49- // Release is the interface to use the oc command to the get image info
50+ // Release is the interface to use the oc command to the get image info.
5051type Release interface {
5152 GetBaseIso (architecture string ) (string , error )
5253 GetBaseIsoVersion (architecture string ) (string , error )
@@ -60,7 +61,7 @@ type release struct {
6061 mirrorConfig []mirror.RegistriesConfig
6162}
6263
63- // NewRelease is used to set up the executor to run oc commands
64+ // NewRelease is used to set up the executor to run oc commands.
6465func NewRelease (config Config , releaseImage string , pullSecret string , mirrorConfig []mirror.RegistriesConfig ) Release {
6566 return & release {
6667 config : config ,
@@ -70,13 +71,6 @@ func NewRelease(config Config, releaseImage string, pullSecret string, mirrorCon
7071 }
7172}
7273
73- const (
74- templateGetImage = "oc adm release info --image-for=%s --filter-by-os=linux/%s --insecure=%t %s"
75- templateGetImageWithIcsp = "oc adm release info --image-for=%s --filter-by-os=linux/%s --insecure=%t --icsp-file=%s %s"
76- templateImageExtract = "oc image extract --path %s:%s --filter-by-os=linux/%s --confirm %s"
77- templateImageExtractWithIcsp = "oc image extract --path %s:%s --filter-by-os=linux/%s --confirm --icsp-file=%s %s"
78- )
79-
8074// ExtractFile extracts the specified file from the given image name, and store it in the cache dir.
8175func (r * release ) ExtractFile (image string , filename string , architecture string ) ([]string , error ) {
8276 imagePullSpec , err := r .getImageFromRelease (image , architecture )
@@ -171,7 +165,6 @@ func (r *release) GetBaseIsoVersion(architecture string) (string, error) {
171165func (r * release ) getImageFromRelease (imageName string , architecture string ) (string , error ) {
172166 // This requires the 'oc' command so make sure its available
173167 _ , err := exec .LookPath ("oc" )
174- var cmd string
175168 if err != nil {
176169 if len (r .mirrorConfig ) > 0 {
177170 logrus .Warning ("Unable to validate mirror config because \" oc\" command is not available" )
@@ -182,21 +175,32 @@ func (r *release) getImageFromRelease(imageName string, architecture string) (st
182175 }
183176
184177 archName := arch .GoArch (architecture )
185-
178+ imagefor := "--image-for=" + imageName
179+ filterbyos := "--filter-by-os=linux/" + archName
180+ insecure := "--insecure=true"
181+
182+ var cmd = []string {
183+ "oc" ,
184+ "adm" ,
185+ "release" ,
186+ "info" ,
187+ imagefor ,
188+ filterbyos ,
189+ insecure ,
190+ }
186191 if len (r .mirrorConfig ) > 0 {
187192 logrus .Debugf ("Using mirror configuration" )
188193 icspFile , err := getIcspFileFromRegistriesConfig (r .mirrorConfig )
189194 if err != nil {
190195 return "" , err
191196 }
192197 defer removeIcspFile (icspFile )
193- cmd = fmt .Sprintf (templateGetImageWithIcsp , imageName , archName , true , icspFile , r .releaseImage )
194- } else {
195- cmd = fmt .Sprintf (templateGetImage , imageName , archName , true , r .releaseImage )
198+ icspfile := "--icsp-file=" + icspFile
199+ cmd = append (cmd , icspfile )
196200 }
197-
201+ cmd = append ( cmd , r . releaseImage )
198202 logrus .Debugf ("Fetching image from OCP release (%s)" , cmd )
199- image , err := execute (r .pullSecret , cmd )
203+ image , err := agent . ExecuteOC (r .pullSecret , cmd )
200204 if err != nil {
201205 if strings .Contains (err .Error (), "unknown flag: --icsp-file" ) {
202206 logrus .Warning ("Using older version of \" oc\" that does not support mirroring" )
@@ -208,26 +212,36 @@ func (r *release) getImageFromRelease(imageName string, architecture string) (st
208212}
209213
210214func (r * release ) extractFileFromImage (image , file , cacheDir string , architecture string ) ([]string , error ) {
211- var cmd string
212215 archName := arch .GoArch (architecture )
216+ extractpath := "--path=" + file + ":" + cacheDir
217+ filterbyos := "--filter-by-os=linux/" + archName
218+
219+ var cmd = []string {
220+ "oc" ,
221+ "image" ,
222+ "extract" ,
223+ extractpath ,
224+ filterbyos ,
225+ "--confirm" ,
226+ }
227+
213228 if len (r .mirrorConfig ) > 0 {
214229 icspFile , err := getIcspFileFromRegistriesConfig (r .mirrorConfig )
215230 if err != nil {
216231 return nil , err
217232 }
218233 defer removeIcspFile (icspFile )
219- cmd = fmt .Sprintf (templateImageExtractWithIcsp , file , cacheDir , archName , icspFile , image )
220- } else {
221- cmd = fmt .Sprintf (templateImageExtract , file , cacheDir , archName , image )
234+ icspfile := "--icsp-file=" + icspFile
235+ cmd = append (cmd , icspfile )
222236 }
223237 path := filepath .Join (cacheDir , path .Base (file ))
224238 // Remove file if it exists
225239 if err := removeCacheFile (path ); err != nil {
226240 return nil , err
227241 }
228-
242+ cmd = append ( cmd , image )
229243 logrus .Debugf ("extracting %s to %s, %s" , file , cacheDir , cmd )
230- _ , err := retry .Do (r .config .MaxTries , r .config .RetryDelay , execute , r .pullSecret , cmd )
244+ _ , err := retry .Do (r .config .MaxTries , r .config .RetryDelay , agent . ExecuteOC , r .pullSecret , cmd )
231245 if err != nil {
232246 return nil , err
233247 }
@@ -244,7 +258,7 @@ func (r *release) extractFileFromImage(image, file, cacheDir string, architectur
244258 return matches , nil
245259}
246260
247- // Get hash from rhcos.json
261+ // Get hash from rhcos.json.
248262func getHashFromInstaller (architecture string ) (bool , string ) {
249263 // Get hash from metadata in the installer
250264 ctx , cancel := context .WithTimeout (context .TODO (), 30 * time .Second )
@@ -277,7 +291,7 @@ func matchingHash(imageSha []byte, sha string) bool {
277291 return false
278292}
279293
280- // Check if there is a different base ISO in the release payload
294+ // Check if there is a different base ISO in the release payload.
281295func (r * release ) verifyCacheFile (image , file , architecture string ) (bool , error ) {
282296 // Get hash of cached file
283297 f , err := os .Open (file )
@@ -343,44 +357,7 @@ func removeCacheFile(path string) error {
343357 return nil
344358}
345359
346- func execute (pullSecret , command string ) (string , error ) {
347- ps , err := os .CreateTemp ("" , "registry-config" )
348- if err != nil {
349- return "" , err
350- }
351- defer func () {
352- ps .Close ()
353- os .Remove (ps .Name ())
354- }()
355- _ , err = ps .Write ([]byte (pullSecret ))
356- if err != nil {
357- return "" , err
358- }
359- // flush the buffer to ensure the file can be read
360- ps .Close ()
361- executeCommand := command [:] + " --registry-config=" + ps .Name ()
362- args := strings .Split (executeCommand , " " )
363-
364- var stdoutBytes , stderrBytes bytes.Buffer
365- cmd := exec .Command (args [0 ], args [1 :]... ) //nolint:gosec
366- cmd .Stdout = & stdoutBytes
367- cmd .Stderr = & stderrBytes
368-
369- err = cmd .Run ()
370- if err == nil {
371- return strings .TrimSpace (stdoutBytes .String ()), nil
372- }
373-
374- var exitErr * exec.ExitError
375- if errors .As (err , & exitErr ) {
376- err = fmt .Errorf ("command '%s' exited with non-zero exit code %d: %s\n %s" , executeCommand , exitErr .ExitCode (), stdoutBytes .String (), stderrBytes .String ())
377- } else {
378- err = fmt .Errorf ("command '%s' failed: %w" , executeCommand , err )
379- }
380- return "" , err
381- }
382-
383- // Create a temporary file containing the ImageContentPolicySources
360+ // Create a temporary file containing the ImageContentPolicySources.
384361func getIcspFileFromRegistriesConfig (mirrorConfig []mirror.RegistriesConfig ) (string , error ) {
385362 contents , err := getIcspContents (mirrorConfig )
386363 if err != nil {
@@ -406,7 +383,7 @@ func getIcspFileFromRegistriesConfig(mirrorConfig []mirror.RegistriesConfig) (st
406383 return icspFile .Name (), nil
407384}
408385
409- // Convert the data in registries.conf into ICSP format
386+ // Convert the data in registries.conf into ICSP format.
410387func getIcspContents (mirrorConfig []mirror.RegistriesConfig ) ([]byte , error ) {
411388 icsp := operatorv1alpha1.ImageContentSourcePolicy {
412389 TypeMeta : metav1.TypeMeta {
0 commit comments