From a61a5bba3803079b2fefd0c89c7801632f5257a5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 25 Feb 2021 18:17:30 +0000 Subject: [PATCH 1/4] vendor: Add coreos/stream-metadata-go This is a new Go library for parsing stream metadata that will be shared by FCOS and RHCOS. --- go.mod | 1 + go.sum | 13 ++ .../coreos/stream-metadata-go/LICENSE | 201 ++++++++++++++++++ .../coreos/stream-metadata-go/arch/arch.go | 48 +++++ .../stream-metadata-go/stream/rhcos/rhcos.go | 18 ++ .../stream-metadata-go/stream/stream.go | 74 +++++++ .../stream-metadata-go/stream/stream_utils.go | 47 ++++ vendor/modules.txt | 5 + 8 files changed, 407 insertions(+) create mode 100644 vendor/github.com/coreos/stream-metadata-go/LICENSE create mode 100644 vendor/github.com/coreos/stream-metadata-go/arch/arch.go create mode 100644 vendor/github.com/coreos/stream-metadata-go/stream/rhcos/rhcos.go create mode 100644 vendor/github.com/coreos/stream-metadata-go/stream/stream.go create mode 100644 vendor/github.com/coreos/stream-metadata-go/stream/stream_utils.go diff --git a/go.mod b/go.mod index 39fa22ebb3f..db8b12b2b60 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/clarketm/json v1.14.1 github.com/containers/image v3.0.2+incompatible github.com/coreos/ignition/v2 v2.9.0 + github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/dmacvicar/terraform-provider-libvirt v0.6.4-0.20201216193629-2b60d7626ff8 github.com/fatih/color v1.10.0 // indirect github.com/frankban/quicktest v1.7.2 // indirect diff --git a/go.sum b/go.sum index f892207af1a..678df24ba2f 100644 --- a/go.sum +++ b/go.sum @@ -302,6 +302,19 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/prometheus-operator v0.35.0/go.mod h1:XHYZUStZWcwd1yk/1DjZv/fywqKIyAJ6pSwvIr+v9BQ= +github.com/coreos/prometheus-operator v0.38.0/go.mod h1:xZC7/TgeC0/mBaJk+1H9dbHaiEvLYHgX6Mi1h40UPh8= +github.com/coreos/stream-metadata-go v0.0.0-20210115160721-ba77d4e64952 h1:t7IgMcyflINfXWPISnHTXwa/F+NxLgWGRGejoyfHUII= +github.com/coreos/stream-metadata-go v0.0.0-20210115160721-ba77d4e64952/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= +github.com/coreos/stream-metadata-go v0.0.0-20210119202048-fb3ac10789fb h1:a1FamXpn1idyCsvXOAEdlmAWDZi6baC6sP2mJ/iHiHs= +github.com/coreos/stream-metadata-go v0.0.0-20210119202048-fb3ac10789fb/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= +github.com/coreos/stream-metadata-go v0.0.0-20210120211222-7575c72c6f05 h1:GXgmcV54WyU3LDXRwf3vXtgkmajMHoYfQ/qCuPblr4A= +github.com/coreos/stream-metadata-go v0.0.0-20210120211222-7575c72c6f05/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= +github.com/coreos/stream-metadata-go v0.0.0-20210121193119-2fbf8747cee7 h1:6LNM7FalzC7155uc5ecuUmD1x70QsOexZYGVHnLc4OE= +github.com/coreos/stream-metadata-go v0.0.0-20210121193119-2fbf8747cee7/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= +github.com/coreos/stream-metadata-go v0.0.0-20210216154348-7c4d5d7d95b5 h1:rFS+eq6Wghj4SOylbWmWcYWkAho4+35NHIMZBv9EozA= +github.com/coreos/stream-metadata-go v0.0.0-20210216154348-7c4d5d7d95b5/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= +github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 h1:0JspqV66RwYqYfvi8lCUoL5zUZMh9uN4hx/J5+NRXIE= +github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3/go.mod h1:RTjQyHgO/G37oJ3qnqYK6Z4TPZ5EsaabOtfMjVXmgko= github.com/coreos/vcontext v0.0.0-20190529201340-22b159166068/go.mod h1:E+6hug9bFSe0KZ2ZAzr8M9F5JlArJjv5D1JS7KSkPKE= github.com/coreos/vcontext v0.0.0-20191017033345-260217907eb5/go.mod h1:E+6hug9bFSe0KZ2ZAzr8M9F5JlArJjv5D1JS7KSkPKE= github.com/coreos/vcontext v0.0.0-20200225161404-ee043618d38d/go.mod h1:z4pMVvaUrxs98RROlIYdAQCKhEicjnTirOaVyDRH5h8= diff --git a/vendor/github.com/coreos/stream-metadata-go/LICENSE b/vendor/github.com/coreos/stream-metadata-go/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/vendor/github.com/coreos/stream-metadata-go/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/stream-metadata-go/arch/arch.go b/vendor/github.com/coreos/stream-metadata-go/arch/arch.go new file mode 100644 index 00000000000..d4a3e6b79ef --- /dev/null +++ b/vendor/github.com/coreos/stream-metadata-go/arch/arch.go @@ -0,0 +1,48 @@ +// package arch contains mappings between the Golang architecture and +// the RPM architecture used by Fedora CoreOS and derivatives. +package arch + +import "runtime" + +type mapping struct { + rpmArch string + goArch string +} + +// If an architecture isn't defined here, we assume it's +// pass through. +var translations = []mapping{ + { + rpmArch: "x86_64", + goArch: "amd64", + }, + { + rpmArch: "aarch64", + goArch: "arm64", + }, +} + +// CurrentRpmArch returns the current architecture in RPM terms. +func CurrentRpmArch() string { + return RpmArch(runtime.GOARCH) +} + +// RpmArch translates a Go architecture to RPM. +func RpmArch(goarch string) string { + for _, m := range translations { + if m.goArch == goarch { + return m.rpmArch + } + } + return goarch +} + +// GoArch translates an RPM architecture to Go. +func GoArch(rpmarch string) string { + for _, m := range translations { + if m.rpmArch == rpmarch { + return m.goArch + } + } + return rpmarch +} diff --git a/vendor/github.com/coreos/stream-metadata-go/stream/rhcos/rhcos.go b/vendor/github.com/coreos/stream-metadata-go/stream/rhcos/rhcos.go new file mode 100644 index 00000000000..320d84b41d4 --- /dev/null +++ b/vendor/github.com/coreos/stream-metadata-go/stream/rhcos/rhcos.go @@ -0,0 +1,18 @@ +package rhcos + +// Extensions is data specific to Red Hat Enterprise Linux CoreOS +type Extensions struct { + AzureDisk *AzureDisk `json:"azure-disk,omitempty"` +} + +// AzureDisk represents an Azure disk image that can be imported +// into an image gallery or otherwise replicated, and then used +// as a boot source for virtual machines. +type AzureDisk struct { + // Release is the source release version + Release string `json:"release"` + // URL to an image already stored in Azure infrastructure + // that can be copied into an image gallery. Avoid creating VMs directly + // from this URL as that may lead to performance limitations. + URL string `json:"url,omitempty"` +} diff --git a/vendor/github.com/coreos/stream-metadata-go/stream/stream.go b/vendor/github.com/coreos/stream-metadata-go/stream/stream.go new file mode 100644 index 00000000000..e3f100cea59 --- /dev/null +++ b/vendor/github.com/coreos/stream-metadata-go/stream/stream.go @@ -0,0 +1,74 @@ +// Package stream models a CoreOS "stream", which is +// a description of the recommended set of binary images for CoreOS. Use +// this API to find cloud images, bare metal disk images, etc. +package stream + +import ( + "github.com/coreos/stream-metadata-go/stream/rhcos" +) + +// Stream contains artifacts available in a stream +type Stream struct { + Stream string `json:"stream"` + Metadata Metadata `json:"metadata"` + Architectures map[string]Arch `json:"architectures"` +} + +// Metadata for a release or stream +type Metadata struct { + LastModified string `json:"last-modified"` +} + +// Arch contains release details for a particular hardware architecture +type Arch struct { + Artifacts map[string]PlatformArtifacts `json:"artifacts"` + Images Images `json:"images,omitempty"` + // RHELCoreOSExtensions is data specific to Red Hat Enterprise Linux CoreOS + RHELCoreOSExtensions *rhcos.Extensions `json:"rhel-coreos-extensions,omitempty"` +} + +// PlatformArtifacts contains images for a platform +type PlatformArtifacts struct { + Release string `json:"release"` + Formats map[string]ImageFormat `json:"formats"` +} + +// ImageFormat contains all artifacts for a single OS image +type ImageFormat struct { + Disk *Artifact `json:"disk,omitempty"` + Kernel *Artifact `json:"kernel,omitempty"` + Initramfs *Artifact `json:"initramfs,omitempty"` + Rootfs *Artifact `json:"rootfs,omitempty"` +} + +// Artifact represents one image file, plus its metadata +type Artifact struct { + Location string `json:"location"` + Signature string `json:"signature"` + Sha256 string `json:"sha256"` + UncompressedSha256 string `json:"uncompressed-sha256,omitempty"` +} + +// Images contains images available in cloud providers +type Images struct { + Aws *AwsImage `json:"aws,omitempty"` + Gcp *GcpImage `json:"gcp,omitempty"` +} + +// AwsImage represents an image across all AWS regions +type AwsImage struct { + Regions map[string]AwsRegionImage `json:"regions,omitempty"` +} + +// AwsRegionImage represents an image in one AWS region +type AwsRegionImage struct { + Release string `json:"release"` + Image string `json:"image"` +} + +// GcpImage represents a GCP cloud image +type GcpImage struct { + Project string `json:"project,omitempty"` + Family string `json:"family,omitempty"` + Name string `json:"name,omitempty"` +} diff --git a/vendor/github.com/coreos/stream-metadata-go/stream/stream_utils.go b/vendor/github.com/coreos/stream-metadata-go/stream/stream_utils.go new file mode 100644 index 00000000000..ffd779c58a6 --- /dev/null +++ b/vendor/github.com/coreos/stream-metadata-go/stream/stream_utils.go @@ -0,0 +1,47 @@ +package stream + +import "fmt" + +// FormatPrefix describes a stream+architecture combination, intended for prepending to error messages +func (st *Stream) FormatPrefix(archname string) string { + return fmt.Sprintf("%s/%s", st.Stream, archname) +} + +// GetArchitecture loads the architecture-specific builds from a stream, +// with a useful descriptive error message if the architecture is not found. +func (st *Stream) GetArchitecture(archname string) (*Arch, error) { + archdata, ok := st.Architectures[archname] + if !ok { + return nil, fmt.Errorf("stream:%s does not have architecture '%s'", st.Stream, archname) + } + return &archdata, nil +} + +// GetAwsRegionImage returns the release data (AMI and release ID) for a particular +// architecture and region. +func (st *Stream) GetAwsRegionImage(archname, region string) (*AwsRegionImage, error) { + starch, err := st.GetArchitecture(archname) + if err != nil { + return nil, err + } + awsimages := starch.Images.Aws + if awsimages == nil { + return nil, fmt.Errorf("%s: No AWS images", st.FormatPrefix(archname)) + } + var regionVal AwsRegionImage + var ok bool + if regionVal, ok = awsimages.Regions[region]; !ok { + return nil, fmt.Errorf("%s: No AWS images in region %s", st.FormatPrefix(archname), region) + } + + return ®ionVal, nil +} + +// GetAMI returns the AWS machine image for a particular architecture and region. +func (st *Stream) GetAMI(archname, region string) (string, error) { + regionVal, err := st.GetAwsRegionImage(archname, region) + if err != nil { + return "", err + } + return regionVal.Image, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 70c089e7f59..24eec4ab081 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -430,6 +430,11 @@ github.com/coreos/ignition/v2/config/util github.com/coreos/ignition/v2/config/v3_1/types github.com/coreos/ignition/v2/config/v3_2/types github.com/coreos/ignition/v2/config/validate +# github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 +## explicit +github.com/coreos/stream-metadata-go/arch +github.com/coreos/stream-metadata-go/stream +github.com/coreos/stream-metadata-go/stream/rhcos # github.com/coreos/vcontext v0.0.0-20201120045928-b0e13dab675c github.com/coreos/vcontext/json github.com/coreos/vcontext/path From b64d699a13669e36e85e4cfe6fa6313202a7a690 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 19 Jan 2021 18:44:05 +0000 Subject: [PATCH 2/4] Add stream metadata for RHCOS This implements part of the plan from: https://github.com/openshift/os/issues/477 When we originally added the pinned RHCOS metadata `rhcos.json` to the installer, we also changed the coreos-assembler `meta.json` format into an arbitrary new format in the name of some cleanups. In retrospect, this was a big mistake because we now have two formats. Then Fedora CoreOS appeared and added streams JSON as a public API. We decided to unify on streams metadata; there's now a published Go library for it: https://github.com/coreos/stream-metadata-go Among other benefits, it is a single file that supports multiple architectures. UPI installs should now use stream metadata, particularly to find public cloud images. This is exposed via a new `openshift-install coreos print-stream-json` command. This is an important preparatory step for exposing this via `oc` as well as having something in the cluster update to it. HOWEVER as a (really hopefully temporary) hack, we *duplicate* the metadata so that IPI installs use the new stream format, and UPI CI jobs can still use the old format (with different RHCOS versions). We will port the UPI docs and CI jobs after this merges. Co-authored-by: Matthew Staebler --- data/data/rhcos-stream.json | 398 +++++++++++++++++++++++++++ docs/user/aws/install_upi.md | 4 +- docs/user/metal/customization_ipi.md | 10 +- docs/user/openstack/customization.md | 11 +- docs/user/overview.md | 30 ++ hack/update-rhcos-bootimage.py | 19 ++ pkg/asset/cluster/tfvars.go | 21 +- pkg/asset/rhcos/bootstrap_image.go | 45 ++- pkg/asset/rhcos/image.go | 94 ++++--- pkg/rhcos/ami.go | 26 -- pkg/rhcos/azure.go | 24 -- pkg/rhcos/builds.go | 114 ++++---- pkg/rhcos/gcp.go | 30 -- pkg/rhcos/openstack.go | 39 --- pkg/rhcos/qemu.go | 43 --- pkg/rhcos/vmware.go | 43 --- 16 files changed, 639 insertions(+), 312 deletions(-) create mode 100644 data/data/rhcos-stream.json delete mode 100644 pkg/rhcos/ami.go delete mode 100644 pkg/rhcos/azure.go delete mode 100644 pkg/rhcos/gcp.go delete mode 100644 pkg/rhcos/qemu.go delete mode 100644 pkg/rhcos/vmware.go diff --git a/data/data/rhcos-stream.json b/data/data/rhcos-stream.json new file mode 100644 index 00000000000..77700ce7c97 --- /dev/null +++ b/data/data/rhcos-stream.json @@ -0,0 +1,398 @@ +{ + "stream": "rhcos-4.8", + "metadata": { + "last-modified": "2021-03-24T13:05:37Z" + }, + "architectures": { + "ppc64le": { + "artifacts": { + "metal": { + "release": "47.83.202102091015-0", + "formats": { + "4k.raw.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-metal4k.ppc64le.raw.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-metal4k.ppc64le.raw.gz.sig", + "sha256": "f6e4458958f38a7bccae4a89a73134d431b86b183ebcf76542446c959fa2d520", + "uncompressed-sha256": "142ce5a0cb3984611a74d5d9d99ee6e320029802d2bee7c31d6b6b9455f3d293" + } + }, + "iso": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live.ppc64le.iso", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live.ppc64le.iso.sig", + "sha256": "d6fb6f949569461e3f9eb67883fa00b611275bb7d7bd3d9f11beaf1c0b33d389" + } + }, + "pxe": { + "kernel": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live-kernel-ppc64le", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live-kernel-ppc64le.sig", + "sha256": "e310166a16592a5cd1bc152b07fda84278b251dc385cf000c65ed7bb31d254ea" + }, + "initramfs": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live-initramfs.ppc64le.img", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live-initramfs.ppc64le.img.sig", + "sha256": "a15c4eaaf5aa0176fc475e4ec41df4ca0e83595f7a5e561e2de0a26f8a485b60" + }, + "rootfs": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live-rootfs.ppc64le.img", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-live-rootfs.ppc64le.img.sig", + "sha256": "621ed54c0cb5180e7e798778c5c365f04b328aa983bc5a752ecea3a17ffd5bce" + } + }, + "raw.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-metal.ppc64le.raw.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-metal.ppc64le.raw.gz.sig", + "sha256": "d0fa64d744dd731ad3185b39ada8d6eb886c8dbba3e683a30176838bdf20ef9a", + "uncompressed-sha256": "1880a77eed6741e45346102b85b5cceb071d7da5479b1075efd810767a33693c" + } + } + } + }, + "openstack": { + "release": "47.83.202102091015-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-openstack.ppc64le.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-openstack.ppc64le.qcow2.gz.sig", + "sha256": "47865a06d1ca6ae06481ab6f1d52ed6c9fca02ae539a06639c8bea65173a1550", + "uncompressed-sha256": "443ed7133f49e36138ac7c452bedcca2d8fde02f818a43fce1d905d41d0a8cea" + } + } + } + }, + "qemu": { + "release": "47.83.202102091015-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-qemu.ppc64le.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-ppc64le/47.83.202102091015-0/ppc64le/rhcos-47.83.202102091015-0-qemu.ppc64le.qcow2.gz.sig", + "sha256": "dce14413bb0347ffcb793a529ed2b4e39efa2b523a3e63faf552e574752a5aac", + "uncompressed-sha256": "2044dd7198fd1f730c3fe1d68c422be7e06ed57b4ad28bfe402f4836b84be869" + } + } + } + } + }, + "images": {} + }, + "s390x": { + "artifacts": { + "metal": { + "release": "47.83.202102090311-0", + "formats": { + "4k.raw.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-metal4k.s390x.raw.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-metal4k.s390x.raw.gz.sig", + "sha256": "566bca2f1462b4d70f1d7da7a1c7d477252f2e2db6251ee61f6e810c3a450982", + "uncompressed-sha256": "3478e62963f4b0bba45cc41a92cae33e9907cc3e4ed1206ef94a05db4e70b9fe" + } + }, + "iso": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live.s390x.iso", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live.s390x.iso.sig", + "sha256": "e64d8d66bd69e6ea7ebdd9be74abce43e10e0731527ee6662780f20863ffc71c" + } + }, + "pxe": { + "kernel": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live-kernel-s390x", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live-kernel-s390x.sig", + "sha256": "a0f17299369b9ce9e42c874a8cc3658a00e58144fc0f54849ef96d9414d811d0" + }, + "initramfs": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live-initramfs.s390x.img", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live-initramfs.s390x.img.sig", + "sha256": "07e5642b818ee9582f59050657dceecad4683c6c54c2f92b071549c8a4826e05" + }, + "rootfs": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live-rootfs.s390x.img", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-live-rootfs.s390x.img.sig", + "sha256": "79de4fb97a151b051201eb04f291a1b36f54d3968d2c3f31571066da8231945a" + } + }, + "raw.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-metal.s390x.raw.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-metal.s390x.raw.gz.sig", + "sha256": "299bcb3de103f701866904f41e316e7c375fd1e0c4434b068e578a35d11084e1", + "uncompressed-sha256": "ab0b1f6080c472f88dc418610cb6af2dd9e8aff835c9a7b417716f67c3e2e25d" + } + } + } + }, + "openstack": { + "release": "47.83.202102090311-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-openstack.s390x.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-openstack.s390x.qcow2.gz.sig", + "sha256": "4ebac56f35e48ff66b18ed21785f722272bc5b24573c2410f3d63a374eeab6db", + "uncompressed-sha256": "2920cfe9a35e24302127507ab39e54d619c839d910361fe45c0c46dbd9813e7a" + } + } + } + }, + "qemu": { + "release": "47.83.202102090311-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-qemu.s390x.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.7-s390x/47.83.202102090311-0/s390x/rhcos-47.83.202102090311-0-qemu.s390x.qcow2.gz.sig", + "sha256": "80d61716f6ca97e9b5256b2202132dcac169700937b40545ce9cd8ad9e6bbcee", + "uncompressed-sha256": "cc3b8294320a6635bfdf05a380fb931875a57fe6b18118940b1ce2f23ca069a1" + } + } + } + } + }, + "images": {} + }, + "x86_64": { + "artifacts": { + "aws": { + "release": "48.83.202103221318-0", + "formats": { + "vmdk.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-aws.x86_64.vmdk.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-aws.x86_64.vmdk.gz.sig", + "sha256": "df74c7d7e063101efdc0ef2c54dcc780dba52aea744f2166acf32c0de27a2187", + "uncompressed-sha256": "e2cf1919cd67832a2dff5936403a148793214b86b3e1930369db9ae79810bc0e" + } + } + } + }, + "azure": { + "release": "48.83.202103221318-0", + "formats": { + "vhd.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-azure.x86_64.vhd.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-azure.x86_64.vhd.gz.sig", + "sha256": "97a5928cc65cee6500233525f6519c6fee61222a0874eb49de26eccdbe92ab97", + "uncompressed-sha256": "4b8bac9c2f576a1d9845b52c227e731abd22d317baa91fb88b58ccb8aef13530" + } + } + } + }, + "gcp": { + "release": "48.83.202103221318-0", + "formats": { + "tar.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-gcp.x86_64.tar.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-gcp.x86_64.tar.gz.sig", + "sha256": "e37d44e41fba4e0854896cc9fe932e2ea87bf7292fb436f14c54074d50145276" + } + } + } + }, + "ibmcloud": { + "release": "48.83.202103221318-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-ibmcloud.x86_64.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-ibmcloud.x86_64.qcow2.gz.sig", + "sha256": "e6400e3385e7d27de7a14ebd2faa77a41967c5722431f591e206741ffb7e47b8", + "uncompressed-sha256": "9b697d882e78750f7b5cca6198bf7f2d7f83fad72459705548025b378a618dc2" + } + } + } + }, + "metal": { + "release": "48.83.202103221318-0", + "formats": { + "4k.raw.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-metal4k.x86_64.raw.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-metal4k.x86_64.raw.gz.sig", + "sha256": "2aa4cd8fa051d46857936040341d8ce38f851f230bb3cb991795a9de021d5a9e", + "uncompressed-sha256": "b10222db6717752acbbb7b7396e26f43d2bab8193128736fcf91da3cba29d9b8" + } + }, + "iso": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live.x86_64.iso", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live.x86_64.iso.sig", + "sha256": "671b2055eb7cbf35172a591b668d67e49db95f6b48f46264a48d2ea57c56529d" + } + }, + "pxe": { + "kernel": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live-kernel-x86_64", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live-kernel-x86_64.sig", + "sha256": "806623984883fee24f94bb2f5944d87bbc380c43bbf8ca1f40d5b0f1981af8f5" + }, + "initramfs": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live-initramfs.x86_64.img", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live-initramfs.x86_64.img.sig", + "sha256": "15047567c01e189ae17e9ba5d1a35fecac3f5cfe724b59b13bbddd0cfefea6b6" + }, + "rootfs": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live-rootfs.x86_64.img", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-live-rootfs.x86_64.img.sig", + "sha256": "0a8dc2ec128d1979cff024311a63c3651e5027b4edb636ecaf103a30eed12a99" + } + }, + "raw.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-metal.x86_64.raw.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-metal.x86_64.raw.gz.sig", + "sha256": "5535e22dd5ea4c5174058bea8e4392941811f3b2a0409112c67a4ca77f8ec0fe", + "uncompressed-sha256": "7b374a6da510f8b392ff8ab384777d79e636d4fcf782f897cea7512557208698" + } + } + } + }, + "openstack": { + "release": "48.83.202103221318-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-openstack.x86_64.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-openstack.x86_64.qcow2.gz.sig", + "sha256": "323e7ba4ba3448e340946543c963823136e1367ed0b229d2a05e1cf537642bb8", + "uncompressed-sha256": "10f55ea6f71d4dc382183597f9360aad6c6551fcc94aa100bbdadaecfe888452" + } + } + } + }, + "qemu": { + "release": "48.83.202103221318-0", + "formats": { + "qcow2.gz": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-qemu.x86_64.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-qemu.x86_64.qcow2.gz.sig", + "sha256": "795bb00f37fc797517eb29fe4032ae4211ce4c23590e4605899ec07a51818776", + "uncompressed-sha256": "7a84fe943cf7eaed8d500b0aabd8386df07af9d7092e45b5554fa68ebf166505" + } + } + } + }, + "vmware": { + "release": "48.83.202103221318-0", + "formats": { + "ova": { + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-vmware.x86_64.ova", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202103221318-0/x86_64/rhcos-48.83.202103221318-0-vmware.x86_64.ova.sig", + "sha256": "19d15c0815dce4448c6edcca36eebff18f56f829594568f954c0ca914639bafb" + } + } + } + } + }, + "images": { + "aws": { + "regions": { + "af-south-1": { + "release": "48.83.202103221318-0", + "image": "ami-0b5c3b497fe4bc2ea" + }, + "ap-east-1": { + "release": "48.83.202103221318-0", + "image": "ami-0a6976bcfac70580e" + }, + "ap-northeast-1": { + "release": "48.83.202103221318-0", + "image": "ami-06cbc55d814a971e4" + }, + "ap-northeast-2": { + "release": "48.83.202103221318-0", + "image": "ami-045e0e1127cf9d4ff" + }, + "ap-northeast-3": { + "release": "48.83.202103221318-0", + "image": "ami-0afb77eabb999b7bc" + }, + "ap-south-1": { + "release": "48.83.202103221318-0", + "image": "ami-0c0ac18b571fa1298" + }, + "ap-southeast-1": { + "release": "48.83.202103221318-0", + "image": "ami-06c10f60b7fff5dd1" + }, + "ap-southeast-2": { + "release": "48.83.202103221318-0", + "image": "ami-0da31b1166a996615" + }, + "ca-central-1": { + "release": "48.83.202103221318-0", + "image": "ami-044a1b0f991f4d652" + }, + "eu-central-1": { + "release": "48.83.202103221318-0", + "image": "ami-0202025e3392eec53" + }, + "eu-north-1": { + "release": "48.83.202103221318-0", + "image": "ami-02a90294ae67d27a6" + }, + "eu-south-1": { + "release": "48.83.202103221318-0", + "image": "ami-09873171555f02ad5" + }, + "eu-west-1": { + "release": "48.83.202103221318-0", + "image": "ami-0bc1151abfa614bf4" + }, + "eu-west-2": { + "release": "48.83.202103221318-0", + "image": "ami-0be1650f9c65ad6d1" + }, + "eu-west-3": { + "release": "48.83.202103221318-0", + "image": "ami-0007ebc2005ce3bc0" + }, + "me-south-1": { + "release": "48.83.202103221318-0", + "image": "ami-0330aad497d9769a4" + }, + "sa-east-1": { + "release": "48.83.202103221318-0", + "image": "ami-06fb2c7c2b7ec3ff4" + }, + "us-east-1": { + "release": "48.83.202103221318-0", + "image": "ami-0146091f9e1b5ec3f" + }, + "us-east-2": { + "release": "48.83.202103221318-0", + "image": "ami-04e591bf6aa86fd31" + }, + "us-west-1": { + "release": "48.83.202103221318-0", + "image": "ami-02b960e0d5a5dc325" + }, + "us-west-2": { + "release": "48.83.202103221318-0", + "image": "ami-0c6da162537298ad6" + } + } + }, + "gcp": { + "project": "rhcos-cloud", + "name": "rhcos-48-83-202103221318-0-gcp-x86-64" + } + }, + "rhel-coreos-extensions": { + "azure-disk": { + "release": "48.83.202103221318-0", + "url": "https://rhcos.blob.core.windows.net/imagebucket/rhcos-48.83.202103221318-0-azure.x86_64.vhd" + } + } + } + } +} diff --git a/docs/user/aws/install_upi.md b/docs/user/aws/install_upi.md index 90c88b6b65e..9b59ab769a4 100644 --- a/docs/user/aws/install_upi.md +++ b/docs/user/aws/install_upi.md @@ -21,8 +21,8 @@ $ openshift-install create install-config ### Optional: Create Encrypted AMIs The IPI-based installer creates an encrypted AMI by default. If you wish to have an encrypted AMI for UPI-based -installs, you will need to create it directly. You can find a list of the appropriate base AMIs -[here](../../../data/data/rhcos.json). +installs, you will need to create it directly. See [CoreOS bootimages](../overview.md#coreos-bootimages) for more information +about bootimages, including how to find the AMI identifiers. You will make an encrypted copy of the AMI according to the [AWS documentation][encrypted-copy]. diff --git a/docs/user/metal/customization_ipi.md b/docs/user/metal/customization_ipi.md index 850f7a628d7..4882e310d76 100644 --- a/docs/user/metal/customization_ipi.md +++ b/docs/user/metal/customization_ipi.md @@ -24,13 +24,15 @@ When doing a disconnected installation, the baremetal platform has the additional requirement that we have locations to download the RHCOS -images. The installer downloads these from a location described in -[/data/data/rhcos.json](/data/data/rhcos.json), but they can be +images. The installer downloads these from a CoreOS stream metadata +embedded in the installer code, but they can be overridden to point to a local mirror. -The SHA256 parameter in the URLs are required, and should match the -uncompressed SHA256 from rhcos.json. +See [CoreOS bootimages](../overview.md#coreos-bootimages) for more information +about bootimages. +The SHA256 parameter in the URL is required, and should match the +uncompressed SHA256 from the stream metadata JSON. * `bootstrapOSImage` (optional string): Override the image used for the bootstrap virtual machine. diff --git a/docs/user/openstack/customization.md b/docs/user/openstack/customization.md index 0015005c0ff..4cfde9feba3 100644 --- a/docs/user/openstack/customization.md +++ b/docs/user/openstack/customization.md @@ -112,13 +112,18 @@ sshKey: ssh-ed25519 AAAA... ## Image Overrides -Normally the installer downloads the RHCOS image from a predetermined location described in [data/data/rhcos.json](/data/data/rhcos.json)). But the download URL can be overridden, notably for disconnected installations. +The OpenShift installer pins the version of RHEL CoreOS and normally handles uploading the image to the target OpenStack instance. -To do so and upload binary data from a custom location the user may set `clusterOSImage` parameter in the install config that points to that location, and then start the installation. In all other respects the process will be consistent with the default. +If you want to download the image manually, see [CoreOS bootimages](../overview.md#coreos-bootimages) for more information +about bootimages. This is useful, for example, to perform a disconnected installation. To do this, +download the `qcow2` and host it at a custom location. Then set the `openstack.clusterOSImage` +parameter field in the install config to point to that location. The install process will +then use that mirrored image. +In all other respects the process will be consistent with the default. **NOTE:** For this to work, the parameter value must be a valid http(s) URL. -**NOTE:** The optional `sha256` query parameter can be attached to the URL, which will force the installer to check the image file checksum before uploading it into Glance. +**NOTE:** The optional `sha256` query parameter can be attached to the URL. This will force the installer to check the uncompressed image file checksum before uploading it into Glance. Example: diff --git a/docs/user/overview.md b/docs/user/overview.md index 521069117a1..28152c45685 100644 --- a/docs/user/overview.md +++ b/docs/user/overview.md @@ -84,3 +84,33 @@ As the unstable warning suggests, the presence of `manifests` and the names and It is occasionally useful to make alterations like this as one-off changes, but don't expect them to work on subsequent installer releases. [cluster-version]: https://github.com/openshift/cluster-version-operator/blob/master/docs/dev/clusterversion.md + +### CoreOS bootimages + +The `openshift-install` binary contains pinned versions of RHEL CoreOS "bootimages" (e.g. OpenStack `qcow2`, AWS AMI, bare metal `.iso`). +Fully automated installs use these by default. + +For UPI (User Provisioned Infrastructure) installs, you can use the `openshift-install coreos print-stream-json` command to access information +about the bootimages in [CoreOS Stream Metadata](https://github.com/coreos/stream-metadata-go) format. + +For example, this command will print the `x86_64` AMI for `us-west-1`: + +``` +$ openshift-install coreos print-stream-json | jq -r '.architectures.x86_64.images.aws.regions["us-west-1"].image' +ami-0c548bdf93b74cd59 +``` + +For on-premise clouds (e.g. OpenStack) with UPI installs, you may need to manually copy +a bootimage into the infrastructure. Here's an example command to print the `x86_64` `qcow2` file for `openstack`: + +``` +$ openshift-install coreos print-stream-json | jq -r '.architectures.x86_64.artifacts.openstack.formats["qcow2.gz"]' +{ + "disk": { + "location": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202102230316-0/x86_64/rhcos-48.83.202102230316-0-openstack.x86_64.qcow2.gz", + "signature": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.8/48.83.202102230316-0/x86_64/rhcos-48.83.202102230316-0-openstack.x86_64.qcow2.gz.sig", + "sha256": "abc2add9746eb7be82e6919ec13aad8e9eae8cf073d8da6126d7c95ea0dee962", + "uncompressed-sha256": "9ed73a4e415ac670535c2188221e5a4a5f3e945bc2e03a65b1ed4fc76e5db6f2" + } +} +``` diff --git a/hack/update-rhcos-bootimage.py b/hack/update-rhcos-bootimage.py index ba2ff1af0a2..9be44086c35 100755 --- a/hack/update-rhcos-bootimage.py +++ b/hack/update-rhcos-bootimage.py @@ -1,4 +1,23 @@ #!/usr/bin/env python3 +# As of 4.8 we are aiming to switch to stream metadata: +# https://github.com/openshift/enhancements/pull/679 +# That transition hasn't yet fully completed; there are two copies of the +# RHCOS metadata: +# +# - data/data/rhcos-4.8.json (stream format, 4.8+) +# - data/data/rhcos-$arch.json (openshift/installer specific, 4.7 and below) +# +# See https://github.com/coreos/coreos-assembler/pull/2000 in particular. +# +# The initial file data/data/rhcos-4.8 was generated this way: +# +# $ plume cosa2stream --name rhcos-4.8 --distro rhcos x86_64=48.83.202102230316-0 s390x=47.83.202102090311-0 ppc64le=47.83.202102091015-0 > data/data/rhcos-4.8.json +# +# To update the bootimage for one or more architectures, use e.g. +# +# $ plume cosa2stream --target data/data/rhcos-4.8.json --distro rhcos x86_64=48.83.202102230316-0 s390x=47.83.202102090311-0 ppc64le=47.83.202102091015-0 +# +# To update the legacy metadata, use: # Usage: ./hack/update-rhcos-bootimage.py https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.6/46.82.202008260918-0/x86_64/meta.json amd64 import codecs,os,sys,json,argparse import urllib.parse diff --git a/pkg/asset/cluster/tfvars.go b/pkg/asset/cluster/tfvars.go index 2c4fee7dd41..41c5399c5fc 100644 --- a/pkg/asset/cluster/tfvars.go +++ b/pkg/asset/cluster/tfvars.go @@ -9,6 +9,7 @@ import ( "strings" igntypes "github.com/coreos/ignition/v2/config/v3_2/types" + coreosarch "github.com/coreos/stream-metadata-go/arch" gcpprovider "github.com/openshift/cluster-api-provider-gcp/pkg/apis/gcpprovider/v1beta1" kubevirtprovider "github.com/openshift/cluster-api-provider-kubevirt/pkg/apis/kubevirtprovider/v1alpha1" kubevirtutils "github.com/openshift/cluster-api-provider-kubevirt/pkg/utils" @@ -338,16 +339,30 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error { } preexistingnetwork := installConfig.Config.GCP.Network != "" - imageRaw, err := rhcospkg.GCPRaw(ctx, installConfig.Config.ControlPlane.Architecture) + archName := coreosarch.RpmArch(string(installConfig.Config.ControlPlane.Architecture)) + st, err := rhcospkg.FetchCoreOSBuild(ctx) if err != nil { - return errors.Wrap(err, "failed to find Raw GCP image URL") + return err + } + streamArch, err := st.GetArchitecture(archName) + if err != nil { + return err + } + + img := streamArch.Images.Gcp + if img == nil { + return fmt.Errorf("%s: No GCP build found", st.FormatPrefix(archName)) } + // For backwards compatibility, we generate this URL to the image (only applies to RHCOS, not FCOS/OKD) + // right now. It will only be used if nested virt or other licenses are enabled, which we + // really should deprecate and remove - xref https://github.com/openshift/installer/pull/4696 + imageURL := fmt.Sprintf("https://storage.googleapis.com/rhcos/rhcos/%s.tar.gz", img.Name) data, err := gcptfvars.TFVars( gcptfvars.TFVarsSources{ Auth: auth, MasterConfigs: masterConfigs, WorkerConfigs: workerConfigs, - ImageURI: imageRaw, + ImageURI: imageURL, ImageLicenses: installConfig.Config.GCP.Licenses, PublicZoneName: publicZoneName, PublishStrategy: installConfig.Config.Publish, diff --git a/pkg/asset/rhcos/bootstrap_image.go b/pkg/asset/rhcos/bootstrap_image.go index 6fde584b5ba..ca750c47537 100644 --- a/pkg/asset/rhcos/bootstrap_image.go +++ b/pkg/asset/rhcos/bootstrap_image.go @@ -3,8 +3,11 @@ package rhcos import ( "context" + "fmt" "time" + "github.com/coreos/stream-metadata-go/arch" + "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/rhcos" @@ -37,28 +40,44 @@ func (i *BootstrapImage) Generate(p asset.Parents) error { p.Get(ic) config := ic.Config - var osimage string - var err error ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) defer cancel() + switch config.Platform.Name() { case baremetal.Name: - // Check for RHCOS image URL override - if boi := config.Platform.BareMetal.BootstrapOSImage; boi != "" { - osimage = boi - break + archName := arch.RpmArch(string(config.ControlPlane.Architecture)) + st, err := rhcos.FetchCoreOSBuild(ctx) + if err != nil { + return err + } + streamArch, err := st.GetArchitecture(archName) + if err != nil { + return err } + // Check for CoreOS image URL override + if boi := config.Platform.BareMetal.BootstrapOSImage; boi != "" { + *i = BootstrapImage(boi) + return nil + } // Baremetal IPI launches a local VM for the bootstrap node // Hence requires the QEMU image to use the libvirt backend - osimage, err = rhcos.QEMU(ctx, config.ControlPlane.Architecture) + if a, ok := streamArch.Artifacts["qemu"]; ok { + u, err := rhcos.FindArtifactURL(a) + if err != nil { + return err + } + *i = BootstrapImage(u) + return nil + } + return fmt.Errorf("%s: No qemu build found", st.FormatPrefix(archName)) default: // other platforms use the same image for all nodes - osimage, err = osImage(config) - } - if err != nil { - return err + u, err := osImage(config) + if err != nil { + return err + } + *i = BootstrapImage(u) + return nil } - *i = BootstrapImage(osimage) - return nil } diff --git a/pkg/asset/rhcos/image.go b/pkg/asset/rhcos/image.go index 12ca213c0ac..5f834acd4b3 100644 --- a/pkg/asset/rhcos/image.go +++ b/pkg/asset/rhcos/image.go @@ -7,7 +7,7 @@ import ( "os" "time" - "github.com/pkg/errors" + "github.com/coreos/stream-metadata-go/arch" "github.com/sirupsen/logrus" "github.com/openshift/installer/pkg/asset" @@ -66,67 +66,95 @@ func (i *Image) Generate(p asset.Parents) error { } func osImage(config *types.InstallConfig) (string, error) { - arch := config.ControlPlane.Architecture - - var osimage string - var err error ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) defer cancel() + + archName := arch.RpmArch(string(config.ControlPlane.Architecture)) + + st, err := rhcos.FetchCoreOSBuild(ctx) + if err != nil { + return "", err + } + streamArch, err := st.GetArchitecture(archName) + if err != nil { + return "", err + } switch config.Platform.Name() { case aws.Name: if len(config.Platform.AWS.AMIID) > 0 { - osimage = config.Platform.AWS.AMIID - break + return config.Platform.AWS.AMIID, nil } region := config.Platform.AWS.Region if !configaws.IsKnownRegion(config.Platform.AWS.Region) { region = "us-east-1" } - osimage, err = rhcos.AMI(ctx, arch, region) + osimage, err := st.GetAMI(archName, region) + if err != nil { + return "", err + } if region != config.Platform.AWS.Region { osimage = fmt.Sprintf("%s,%s", osimage, region) } + return osimage, nil case gcp.Name: - osimage, err = rhcos.GCP(ctx, arch) + if streamArch.Images.Gcp != nil { + img := streamArch.Images.Gcp + return fmt.Sprintf("projects/%s/global/images/%s", img.Project, img.Name), nil + } + return "", fmt.Errorf("%s: No GCP build found", st.FormatPrefix(archName)) case libvirt.Name: - osimage, err = rhcos.QEMU(ctx, arch) - case openstack.Name: - if oi := config.Platform.OpenStack.ClusterOSImage; oi != "" { - osimage = oi - break + // 𝅘𝅥𝅮 Everything's going to be a-ok 𝅘𝅥𝅮 + if a, ok := streamArch.Artifacts["qemu"]; ok { + return rhcos.FindArtifactURL(a) + } + return "", fmt.Errorf("%s: No qemu build found", st.FormatPrefix(archName)) + case ovirt.Name, kubevirt.Name, openstack.Name: + op := config.Platform.OpenStack + if op != nil { + if oi := op.ClusterOSImage; oi != "" { + return oi, nil + } + } + if a, ok := streamArch.Artifacts["openstack"]; ok { + return rhcos.FindArtifactURL(a) } - osimage, err = rhcos.OpenStack(ctx, arch) - case ovirt.Name: - osimage, err = rhcos.OpenStack(ctx, arch) - case kubevirt.Name: - osimage, err = rhcos.OpenStack(ctx, arch) + return "", fmt.Errorf("%s: No openstack build found", st.FormatPrefix(archName)) case azure.Name: - osimage, err = rhcos.VHD(ctx, arch) + ext := streamArch.RHELCoreOSExtensions + if ext == nil { + return "", fmt.Errorf("%s: No azure build found", st.FormatPrefix(archName)) + } + azd := ext.AzureDisk + if azd == nil { + return "", fmt.Errorf("%s: No azure build found", st.FormatPrefix(archName)) + } + return azd.URL, nil case baremetal.Name: - // Check for RHCOS image URL override + // Check for image URL override if oi := config.Platform.BareMetal.ClusterOSImage; oi != "" { - osimage = oi - break + return oi, nil } // Note that baremetal IPI currently uses the OpenStack image // because this contains the necessary ironic config drive // ignition support, which isn't enabled in the UPI BM images - osimage, err = rhcos.OpenStack(ctx, arch) + if a, ok := streamArch.Artifacts["openstack"]; ok { + return rhcos.FindArtifactURL(a) + } + return "", fmt.Errorf("%s: No openstack build found", st.FormatPrefix(archName)) case vsphere.Name: - // Check for RHCOS image URL override + // Check for image URL override if config.Platform.VSphere.ClusterOSImage != "" { - osimage = config.Platform.VSphere.ClusterOSImage - break + return config.Platform.VSphere.ClusterOSImage, nil } - osimage, err = rhcos.VMware(ctx, arch) + if a, ok := streamArch.Artifacts["vmware"]; ok { + return rhcos.FindArtifactURL(a) + } + return "", fmt.Errorf("%s: No vmware build found", st.FormatPrefix(archName)) case none.Name: + return "", nil default: - return "", errors.New("invalid Platform") - } - if err != nil { - return "", err + return "", fmt.Errorf("invalid platform %v", config.Platform.Name()) } - return osimage, nil } diff --git a/pkg/rhcos/ami.go b/pkg/rhcos/ami.go deleted file mode 100644 index 04cb15db911..00000000000 --- a/pkg/rhcos/ami.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:generate go run ami_regions_generate.go rhcos ../../data/data/rhcos-amd64.json ami_regions.go - -package rhcos - -import ( - "context" - - "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" -) - -// AMI fetches the HVM AMI ID of the Red Hat Enterprise Linux CoreOS release. -func AMI(ctx context.Context, arch types.Architecture, region string) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - ami, ok := meta.AMIs[region] - if !ok { - return "", errors.Errorf("no RHCOS AMIs found in %s", region) - } - - return ami.HVM, nil -} diff --git a/pkg/rhcos/azure.go b/pkg/rhcos/azure.go deleted file mode 100644 index 14e8fc30bb2..00000000000 --- a/pkg/rhcos/azure.go +++ /dev/null @@ -1,24 +0,0 @@ -package rhcos - -import ( - "context" - - "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" -) - -// VHD fetches the URL of the public Azure storage bucket containing the RHCOS image -func VHD(ctx context.Context, arch types.Architecture) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - url := meta.Azure.URL - if url == "" { - return "", errors.New("no RHCOS Azure URL found") - } - - return url, nil -} diff --git a/pkg/rhcos/builds.go b/pkg/rhcos/builds.go index 76d0b64415f..6bcdb68a797 100644 --- a/pkg/rhcos/builds.go +++ b/pkg/rhcos/builds.go @@ -1,3 +1,8 @@ +// package rhcos contains APIs for interacting with the RHEL (or Fedora) CoreOS +// bootimages embedded as stream metadata JSON with the installer +// For more information, see +// https://github.com/openshift/enhancements/pull/679 + package rhcos import ( @@ -5,69 +10,80 @@ import ( "encoding/json" "fmt" "io/ioutil" - "os" + "net/url" + "github.com/coreos/stream-metadata-go/stream" "github.com/openshift/installer/data" "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" ) -var ( - errInvalidArch = fmt.Errorf("no build metadata for given architecture") -) - -type metadata struct { - AMIs map[string]struct { - HVM string `json:"hvm"` - } `json:"amis"` - Azure struct { - Image string `json:"image"` - URL string `json:"url"` +// FetchRawCoreOSStream returns the raw stream metadata for the +// bootimages embedded in the installer. +func FetchRawCoreOSStream(ctx context.Context) ([]byte, error) { + file, err := data.Assets.Open("rhcos-stream.json") + if err != nil { + return nil, errors.Wrapf(err, "failed to read embedded CoreOS stream metadata") } - GCP struct { - Image string `json:"image"` - Project string `json:"project"` - URL string `json:"url"` + defer file.Close() + + body, err := ioutil.ReadAll(file) + if err != nil { + return nil, errors.Wrap(err, "failed to read CoreOS stream metadata") } - BaseURI string `json:"baseURI"` - Images struct { - QEMU struct { - Path string `json:"path"` - SHA256 string `json:"sha256"` - UncompressedSHA256 string `json:"uncompressed-sha256"` - } `json:"qemu"` - OpenStack struct { - Path string `json:"path"` - SHA256 string `json:"sha256"` - UncompressedSHA256 string `json:"uncompressed-sha256"` - } `json:"openstack"` - VMware struct { - Path string `json:"path"` - SHA256 string `json:"sha256"` - } `json:"vmware"` - } `json:"images"` - OSTreeVersion string `json:"ostree-version"` + return body, nil } -func fetchRHCOSBuild(ctx context.Context, arch types.Architecture) (*metadata, error) { - file, err := data.Assets.Open(fmt.Sprintf("rhcos-%s.json", arch)) +// FetchCoreOSBuild returns the pinned version of RHEL/Fedora CoreOS used +// by the installer to provision the bootstrap node and control plane currently. +// For more information, see e.g. https://github.com/openshift/enhancements/pull/201 +func FetchCoreOSBuild(ctx context.Context) (*stream.Stream, error) { + body, err := FetchRawCoreOSStream(ctx) if err != nil { return nil, err } - defer file.Close() - - body, err := ioutil.ReadAll(file) - if os.IsNotExist(err) { - return nil, errInvalidArch - } else if err != nil { - return nil, err + var st stream.Stream + if err := json.Unmarshal(body, &st); err != nil { + return nil, errors.Wrap(err, "failed to parse CoreOS stream metadata") } + return &st, nil +} - var meta *metadata - if err := json.Unmarshal(body, &meta); err != nil { - return meta, errors.Wrap(err, "failed to parse RHCOS build metadata") +// FormatURLWithIntegrity squashes an artifact into a URL string +// with the uncompressed sha256 as a query parameter. This is necessary +// currently because various parts of the installer pass around this +// reference as a string, and it's also exposed to users via install-config overrides. +func FormatURLWithIntegrity(artifact *stream.Artifact) (string, error) { + u, err := url.Parse(artifact.Location) + if err != nil { + return "", fmt.Errorf("failed to parse artifact URL: %v", err) } + q := u.Query() + q.Set("sha256", artifact.UncompressedSha256) + u.RawQuery = q.Encode() + return u.String(), nil +} - return meta, nil +// FindArtifactURL returns a single "disk" artifact type; this +// mainly abstracts over e.g. `qcow2.xz` and `qcow2.gz`. (FCOS uses +// xz, RHCOS uses gzip right now) +// +// Use this function only for cases where there's a single artifact type, such +// as `qemu` and `openstack`. +// +// Some platforms have multiple artifact types; for example, `metal` has an ISO +// as well as PXE files. This function will error in such a case. +func FindArtifactURL(artifacts stream.PlatformArtifacts) (string, error) { + var artifact *stream.Artifact + for _, v := range artifacts.Formats { + if v.Disk != nil { + if artifact != nil { + return "", fmt.Errorf("multiple \"disk\" artifacts found") + } + artifact = v.Disk + } + } + if artifact != nil { + return FormatURLWithIntegrity(artifact) + } + return "", fmt.Errorf("no \"disk\" artifact found") } diff --git a/pkg/rhcos/gcp.go b/pkg/rhcos/gcp.go deleted file mode 100644 index 96dbbf27833..00000000000 --- a/pkg/rhcos/gcp.go +++ /dev/null @@ -1,30 +0,0 @@ -package rhcos - -import ( - "context" - "fmt" - - "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" -) - -// GCP fetches the URL of the public RHCOS image -func GCP(ctx context.Context, arch types.Architecture) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - return fmt.Sprintf("projects/%s/global/images/%s", meta.GCP.Project, meta.GCP.Image), nil -} - -// GCPRaw fetches the URL of the public GCP storage bucket containing the RHCOS image -func GCPRaw(ctx context.Context, arch types.Architecture) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - return meta.GCP.URL, nil -} diff --git a/pkg/rhcos/openstack.go b/pkg/rhcos/openstack.go index 7f25ac7d815..574ed125a9c 100644 --- a/pkg/rhcos/openstack.go +++ b/pkg/rhcos/openstack.go @@ -1,48 +1,9 @@ package rhcos import ( - "context" "net/url" - - "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" ) -// OpenStack fetches the URL of the Red Hat Enterprise Linux CoreOS release, -// for the openstack platform -func OpenStack(ctx context.Context, arch types.Architecture) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - base, err := url.Parse(meta.BaseURI) - if err != nil { - return "", err - } - - relOpenStack, err := url.Parse(meta.Images.OpenStack.Path) - if err != nil { - return "", err - } - - baseURL := base.ResolveReference(relOpenStack).String() - - // Attach sha256 checksum to the URL. Always provide the - // uncompressed SHA256; the cache will take care of - // uncompressing before checksumming. - baseURL += "?sha256=" + meta.Images.OpenStack.UncompressedSHA256 - - // Check that we have generated a valid URL - _, err = url.ParseRequestURI(baseURL) - if err != nil { - return "", err - } - - return baseURL, nil -} - // GenerateOpenStackImageName returns Glance image name for instances. func GenerateOpenStackImageName(rhcosImage, infraID string) (imageName string, isURL bool) { // Here we check whether rhcosImage is a URL or not. If this is the first case, it means that Glance image diff --git a/pkg/rhcos/qemu.go b/pkg/rhcos/qemu.go deleted file mode 100644 index f0c0026cc80..00000000000 --- a/pkg/rhcos/qemu.go +++ /dev/null @@ -1,43 +0,0 @@ -package rhcos - -import ( - "context" - "net/url" - - "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" -) - -// QEMU fetches the URL of the Red Hat Enterprise Linux CoreOS release. -func QEMU(ctx context.Context, arch types.Architecture) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - base, err := url.Parse(meta.BaseURI) - if err != nil { - return "", err - } - - relQEMU, err := url.Parse(meta.Images.QEMU.Path) - if err != nil { - return "", err - } - - baseURL := base.ResolveReference(relQEMU).String() - - // Attach sha256 checksum to the URL. Always provide the - // uncompressed SHA256; the cache will take care of - // uncompressing before checksumming. - baseURL += "?sha256=" + meta.Images.QEMU.UncompressedSHA256 - - // Check that we have generated a valid URL - _, err = url.ParseRequestURI(baseURL) - if err != nil { - return "", err - } - - return baseURL, nil -} diff --git a/pkg/rhcos/vmware.go b/pkg/rhcos/vmware.go deleted file mode 100644 index d3b1a368f3f..00000000000 --- a/pkg/rhcos/vmware.go +++ /dev/null @@ -1,43 +0,0 @@ -package rhcos - -import ( - "context" - "net/url" - - "github.com/pkg/errors" - - "github.com/openshift/installer/pkg/types" -) - -// VMware fetches the URL of the Red Hat Enterprise Linux CoreOS release. -func VMware(ctx context.Context, arch types.Architecture) (string, error) { - meta, err := fetchRHCOSBuild(ctx, arch) - if err != nil { - return "", errors.Wrap(err, "failed to fetch RHCOS metadata") - } - - base, err := url.Parse(meta.BaseURI) - if err != nil { - return "", err - } - - image, err := url.Parse(meta.Images.VMware.Path) - if err != nil { - return "", err - } - - baseURL := base.ResolveReference(image).String() - - // Attach sha256 checksum to the URL. Always provide the - // uncompressed SHA256; the cache will take care of - // uncompressing before checksumming. - baseURL += "?sha256=" + meta.Images.VMware.SHA256 - - // Check that we have generated a valid URL - _, err = url.ParseRequestURI(baseURL) - if err != nil { - return "", err - } - - return baseURL, nil -} From 3ba64bc3522fd745e6eddd8b691acf3c0e04b5cb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Mar 2021 15:20:36 +0000 Subject: [PATCH 3/4] Add `openshift-install coreos print-stream-json` command Now that we have a standardized JSON format for the bootimages, add a CLI command to print it. This is necessary for UPI installs; previously what we've done for UPI is completely ad-hoc, such as having the docs team copy the AMI list into HTML format. Our UPI CI automation copies `rhcos.json` from the installer git into a container, but customers can't do that. In the past I've even heard of people e.g. searching in AWS for "RHEL CoreOS" and picking AMIs based on that, which is extremely bad because they may not even get something from us. This closes a major gap in allowing customers to automate UPI installs in the same way IPI works. One aside: because the JSON data is embedded in the installer binary, which is in turn embedded in the release image, which is GPG signed, one can transitively verify the integrity via that signature. --- cmd/openshift-install/coreos.go | 11 +++++++++ cmd/openshift-install/main.go | 1 + pkg/coreoscli/cmd.go | 41 +++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 cmd/openshift-install/coreos.go create mode 100644 pkg/coreoscli/cmd.go diff --git a/cmd/openshift-install/coreos.go b/cmd/openshift-install/coreos.go new file mode 100644 index 00000000000..61aa99fe2ba --- /dev/null +++ b/cmd/openshift-install/coreos.go @@ -0,0 +1,11 @@ +package main + +import ( + "github.com/spf13/cobra" + + "github.com/openshift/installer/pkg/coreoscli" +) + +func newCoreOSCmd() *cobra.Command { + return coreoscli.NewCmd() +} diff --git a/cmd/openshift-install/main.go b/cmd/openshift-install/main.go index 48bf7b6ebf0..a7699b6d5f5 100644 --- a/cmd/openshift-install/main.go +++ b/cmd/openshift-install/main.go @@ -60,6 +60,7 @@ func installerMain() { newGatherCmd(), newVersionCmd(), newGraphCmd(), + newCoreOSCmd(), newCompletionCmd(), newMigrateCmd(), newExplainCmd(), diff --git a/pkg/coreoscli/cmd.go b/pkg/coreoscli/cmd.go new file mode 100644 index 00000000000..f8cf5b3ec44 --- /dev/null +++ b/pkg/coreoscli/cmd.go @@ -0,0 +1,41 @@ +package coreoscli + +import ( + "context" + "os" + + "github.com/openshift/installer/pkg/rhcos" + "github.com/spf13/cobra" +) + +// printStreamJSON is the implementation of print-stream-json +func printStreamJSON(cmd *cobra.Command, _ []string) error { + streamData, err := rhcos.FetchRawCoreOSStream(context.Background()) + if err != nil { + return err + } + os.Stdout.Write(streamData) + return nil +} + +// NewCmd returns a subcommand for explain +func NewCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "coreos", + Short: "Commands for operating on CoreOS boot images", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + return cmd.Help() + }, + } + + printStreamCmd := &cobra.Command{ + Use: "print-stream-json", + Short: "Outputs the CoreOS stream metadata for the bootimages", + Args: cobra.ExactArgs(0), + RunE: printStreamJSON, + } + cmd.AddCommand(printStreamCmd) + + return cmd +} From 7a7b055d32ba5b49eb7e0a97e589dc4f3798884e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Mar 2021 14:10:12 +0000 Subject: [PATCH 4/4] Add docs/dev/pinned-coreos.md Briefly describe the history and future of the pinned {RHEL, Fedora} CoreOS metadata in the installer. Co-authored-by: Matthew Staebler --- docs/dev/pinned-coreos.md | 52 ++++++++++++++++++++++++++++++++++ hack/update-rhcos-bootimage.py | 22 ++------------ pkg/rhcos/builds.go | 3 +- 3 files changed, 55 insertions(+), 22 deletions(-) create mode 100644 docs/dev/pinned-coreos.md diff --git a/docs/dev/pinned-coreos.md b/docs/dev/pinned-coreos.md new file mode 100644 index 00000000000..177c48a2cbd --- /dev/null +++ b/docs/dev/pinned-coreos.md @@ -0,0 +1,52 @@ +# CoreOS and the installer + +A key decision made before the release of OpenShift 4 is to pin the CoreOS bootimage in +the installer: https://github.com/openshift/installer/commit/e080f0494708b2674fe37af02f670c8030c32bf6 + +That is still the case today; when one gets an `openshift-install` binary, that +binary contains the 2-tuple `(CoreOS, release image)`, meaning the result of an +install will be the same thing each time. + +More background: + + - https://github.com/openshift/enhancements/pull/201 + - https://github.com/openshift/machine-config-operator/blob/master/docs/OSUpgrades.md + +## Stream metadata + +As of 4.8 the [stream metadata enhancement](https://github.com/openshift/enhancements/blobmaster/enhancements/coreos-bootimages.md) +is in progress which provides a standardized JSON format and injects +that data into the cluster as well. + +### Updating pinned stream metadata + + +To update the bootimage for one or more architectures, use e.g. + +``` +$ plume cosa2stream --target data/data/rhcos-stream.json --distro rhcos x86_64=48.83.202102230316-0 s390x=47.83.202102090311-0 ppc64le=47.83.202102091015-0 +``` + +For more information on this command, see: + +- https://github.com/coreos/coreos-assembler/pull/2000 +- https://github.com/coreos/coreos-assembler/pull/2052 + +### Updating pinned legacy metadata + +To update the legacy metadata, use: + +``` +./hack/update-rhcos-bootimage.py https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.6/46.82.202008260918-0/x86_64/meta.json amd64 +``` + +This will hopefully be removed soon. + +### Origin of stream metadata + + +For historical reference, the initial file `data/data/rhcos-stream.json` was generated this way: + +``` +$ plume cosa2stream --name rhcos-4.8 --distro rhcos x86_64=48.83.202102230316-0 s390x=47.83.202102090311-0 ppc64le=47.83.202102091015-0 > data/data/rhcos-stream.json +``` diff --git a/hack/update-rhcos-bootimage.py b/hack/update-rhcos-bootimage.py index 9be44086c35..c236c50d057 100755 --- a/hack/update-rhcos-bootimage.py +++ b/hack/update-rhcos-bootimage.py @@ -1,24 +1,6 @@ #!/usr/bin/env python3 -# As of 4.8 we are aiming to switch to stream metadata: -# https://github.com/openshift/enhancements/pull/679 -# That transition hasn't yet fully completed; there are two copies of the -# RHCOS metadata: -# -# - data/data/rhcos-4.8.json (stream format, 4.8+) -# - data/data/rhcos-$arch.json (openshift/installer specific, 4.7 and below) -# -# See https://github.com/coreos/coreos-assembler/pull/2000 in particular. -# -# The initial file data/data/rhcos-4.8 was generated this way: -# -# $ plume cosa2stream --name rhcos-4.8 --distro rhcos x86_64=48.83.202102230316-0 s390x=47.83.202102090311-0 ppc64le=47.83.202102091015-0 > data/data/rhcos-4.8.json -# -# To update the bootimage for one or more architectures, use e.g. -# -# $ plume cosa2stream --target data/data/rhcos-4.8.json --distro rhcos x86_64=48.83.202102230316-0 s390x=47.83.202102090311-0 ppc64le=47.83.202102091015-0 -# -# To update the legacy metadata, use: -# Usage: ./hack/update-rhcos-bootimage.py https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.6/46.82.202008260918-0/x86_64/meta.json amd64 +# This script updates the legacy metadata. We hope to remove it soon. +# See docs/dev/pinned-coreos.md for more information. import codecs,os,sys,json,argparse import urllib.parse import urllib.request diff --git a/pkg/rhcos/builds.go b/pkg/rhcos/builds.go index 6bcdb68a797..089a340c363 100644 --- a/pkg/rhcos/builds.go +++ b/pkg/rhcos/builds.go @@ -1,7 +1,6 @@ // package rhcos contains APIs for interacting with the RHEL (or Fedora) CoreOS // bootimages embedded as stream metadata JSON with the installer -// For more information, see -// https://github.com/openshift/enhancements/pull/679 +// For more information, see docs/dev/pinned-coreos.md package rhcos