github.com/openshift/installer@v1.4.17/pkg/rhcos/builds.go (about) 1 // package rhcos contains APIs for interacting with the RHEL (or Fedora) CoreOS 2 // bootimages embedded as stream metadata JSON with the installer 3 // For more information, see docs/dev/pinned-coreos.md 4 5 package rhcos 6 7 import ( 8 "context" 9 "encoding/json" 10 "fmt" 11 "io" 12 "net/url" 13 14 "github.com/coreos/stream-metadata-go/stream" 15 "github.com/pkg/errors" 16 17 "github.com/openshift/installer/data" 18 ) 19 20 // FetchRawCoreOSStream returns the raw stream metadata for the 21 // bootimages embedded in the installer. 22 func FetchRawCoreOSStream(ctx context.Context) ([]byte, error) { 23 file, err := data.Assets.Open(getStreamFileName()) 24 if err != nil { 25 return nil, errors.Wrapf(err, "failed to read embedded CoreOS stream metadata") 26 } 27 defer file.Close() 28 29 body, err := io.ReadAll(file) 30 if err != nil { 31 return nil, errors.Wrap(err, "failed to read CoreOS stream metadata") 32 } 33 return body, nil 34 } 35 36 // FetchCoreOSBuild returns the pinned version of RHEL/Fedora CoreOS used 37 // by the installer to provision the bootstrap node and control plane currently. 38 // For more information, see e.g. https://github.com/openshift/enhancements/pull/201 39 func FetchCoreOSBuild(ctx context.Context) (*stream.Stream, error) { 40 body, err := FetchRawCoreOSStream(ctx) 41 if err != nil { 42 return nil, err 43 } 44 var st stream.Stream 45 if err := json.Unmarshal(body, &st); err != nil { 46 return nil, errors.Wrap(err, "failed to parse CoreOS stream metadata") 47 } 48 return &st, nil 49 } 50 51 // FormatURLWithIntegrity squashes an artifact into a URL string 52 // with the uncompressed sha256 as a query parameter. This is necessary 53 // currently because various parts of the installer pass around this 54 // reference as a string, and it's also exposed to users via install-config overrides. 55 func FormatURLWithIntegrity(artifact *stream.Artifact) (string, error) { 56 u, err := url.Parse(artifact.Location) 57 if err != nil { 58 return "", fmt.Errorf("failed to parse artifact URL: %v", err) 59 } 60 q := u.Query() 61 q.Set("sha256", artifact.UncompressedSha256) 62 u.RawQuery = q.Encode() 63 return u.String(), nil 64 } 65 66 // FindArtifactURL returns a single "disk" artifact type; this 67 // mainly abstracts over e.g. `qcow2.xz` and `qcow2.gz`. (FCOS uses 68 // xz, RHCOS uses gzip right now) 69 // 70 // Use this function only for cases where there's a single artifact type, such 71 // as `qemu` and `openstack`. 72 // 73 // Some platforms have multiple artifact types; for example, `metal` has an ISO 74 // as well as PXE files. This function will error in such a case. 75 func FindArtifactURL(artifacts stream.PlatformArtifacts) (string, error) { 76 var artifact *stream.Artifact 77 for _, v := range artifacts.Formats { 78 if v.Disk != nil { 79 if artifact != nil { 80 return "", fmt.Errorf("multiple \"disk\" artifacts found") 81 } 82 artifact = v.Disk 83 } 84 } 85 if artifact != nil { 86 return FormatURLWithIntegrity(artifact) 87 } 88 return "", fmt.Errorf("no \"disk\" artifact found") 89 }