pax_global_header00006660000000000000000000000064144471210370014515gustar00rootroot0000000000000052 comment=c32d9d072eed9d7e6c82359211c1bb884d250c4a stream-metadata-go-0.4.3/000077500000000000000000000000001444712103700151755ustar00rootroot00000000000000stream-metadata-go-0.4.3/.github/000077500000000000000000000000001444712103700165355ustar00rootroot00000000000000stream-metadata-go-0.4.3/.github/ISSUE_TEMPLATE/000077500000000000000000000000001444712103700207205ustar00rootroot00000000000000stream-metadata-go-0.4.3/.github/ISSUE_TEMPLATE/release-checklist.md000066400000000000000000000016741444712103700246410ustar00rootroot00000000000000--- # Template generated by https://github.com/coreos/repo-templates; do not edit downstream --- Release checklist: Tagging: - [ ] Write release notes in `docs/release-notes.md`. Get them reviewed and merged - [ ] If doing a branched release, also include a PR to merge the `docs/release-notes.md` changes into main - [ ] Ensure your local copy is up to date with the upstream main branch (`git@github.com:coreos/stream-metadata-go.git`) - [ ] Ensure your working directory is clean (`git clean -fdx`) - [ ] Ensure you can sign commits and any yubikeys/smartcards are plugged in - [ ] Run `./tag_release.sh ` - [ ] Push that tag to GitHub GitHub release: - [ ] Find the new tag in the [GitHub tag list](https://github.com/coreos/stream-metadata-go/tags) and click the triple dots menu, and create a draft release for it. - [ ] Copy and paste the release notes from `docs/release-notes.md` - [ ] Publish the release stream-metadata-go-0.4.3/.github/dependabot.yml000066400000000000000000000004161444712103700213660ustar00rootroot00000000000000# Maintained in https://github.com/coreos/repo-templates # Do not edit downstream. version: 2 updates: - package-ecosystem: gomod directory: / schedule: interval: weekly open-pull-requests-limit: 10 labels: - dependency - skip-notes stream-metadata-go-0.4.3/.github/workflows/000077500000000000000000000000001444712103700205725ustar00rootroot00000000000000stream-metadata-go-0.4.3/.github/workflows/go.yml000066400000000000000000000022001444712103700217140ustar00rootroot00000000000000# Maintained in https://github.com/coreos/repo-templates # Do not edit downstream. name: Go on: push: branches: [main] pull_request: branches: [main] permissions: contents: read # don't waste job slots on superseded code concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: test: name: Test strategy: matrix: go-version: [1.18.x, 1.19.x, 1.20.x] os: [ubuntu-latest] include: - go-version: 1.20.x os: macos-latest - go-version: 1.20.x os: windows-latest runs-on: ${{ matrix.os }} steps: - name: Set up Go 1.x uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - name: Check out repository uses: actions/checkout@v3 - name: Check modules run: go mod verify - name: Build shell: bash run: make - name: Test shell: bash run: make test - name: Run linter uses: golangci/golangci-lint-action@v3 if: runner.os == 'Linux' with: version: v1.52.2 args: -E=gofmt --timeout=30m0s stream-metadata-go-0.4.3/.github/workflows/require-release-note.yml000066400000000000000000000011371444712103700253540ustar00rootroot00000000000000# Maintained in https://github.com/coreos/repo-templates # Do not edit downstream. name: Release notes on: pull_request: branches: [main] types: [opened, synchronize, reopened, labeled, unlabeled] permissions: contents: read concurrency: group: release-note-${{ github.ref }} cancel-in-progress: true jobs: require-notes: name: Require release note runs-on: ubuntu-latest steps: - name: Require release-notes.md update uses: coreos/actions-lib/require-file-change@main with: path: docs/release-notes.md override-label: skip-notes stream-metadata-go-0.4.3/LICENSE000066400000000000000000000261351444712103700162110ustar00rootroot00000000000000 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. stream-metadata-go-0.4.3/Makefile000066400000000000000000000005521444712103700166370ustar00rootroot00000000000000PKGS := arch release stream stream/rhcos release/rhcos fedoracoreos BUILD_PKGS = $(foreach pkg,$(PKGS),build-$(pkg)) TEST_PKGS = $(foreach pkg,$(PKGS),test-$(pkg)) build: $(BUILD_PKGS) .PHONY: build $(BUILD_PKGS): build-%: cd $* && go build .PHONY: $(BUILD_PKGS) test: $(TEST_PKGS) .PHONY: test $(TEST_PKGS): test-%: cd $* && go test .PHONY: $(TEST_PKGS) stream-metadata-go-0.4.3/README.md000066400000000000000000000006131444712103700164540ustar00rootroot00000000000000# Go library for parsing Fedora CoreOS streams See the [Fedora CoreOS documentation](https://docs.fedoraproject.org/en-US/fedora-coreos/getting-started/) for basic information about streams. This is a Go library which exposes API to decode streams into Go structs, as well as a convenience API to find the URL for a given stream. # Example usage See [example code here](example/example.go). stream-metadata-go-0.4.3/arch/000077500000000000000000000000001444712103700161125ustar00rootroot00000000000000stream-metadata-go-0.4.3/arch/arch.go000066400000000000000000000016521444712103700173620ustar00rootroot00000000000000// 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 } stream-metadata-go-0.4.3/arch/arch_test.go000066400000000000000000000007771444712103700204300ustar00rootroot00000000000000// package arch contains mappings between the Golang architecture and // the RPM architecture used by Fedora CoreOS and derivatives. package arch import ( "runtime" "testing" "github.com/stretchr/testify/assert" ) func TestMapping(t *testing.T) { // Validate bidirectional mapping for current architecture assert.Equal(t, GoArch(CurrentRpmArch()), runtime.GOARCH) assert.Equal(t, GoArch("x86_64"), "amd64") assert.Equal(t, GoArch("aarch64"), "arm64") assert.Equal(t, GoArch("ppc64le"), "ppc64le") } stream-metadata-go-0.4.3/docs/000077500000000000000000000000001444712103700161255ustar00rootroot00000000000000stream-metadata-go-0.4.3/docs/development.md000066400000000000000000000004211444712103700207660ustar00rootroot00000000000000# Development ## Release process Releases can be performed by [creating a new release ticket][new-release-ticket] and following the steps in the checklist there. [new-release-ticket]: https://github.com/coreos/stream-metadata-go/issues/new?template=release-checklist.md stream-metadata-go-0.4.3/docs/release-notes.md000066400000000000000000000034651444712103700212250ustar00rootroot00000000000000# Release notes ## Upcoming stream-metadata-go 0.4.4 (unreleased) Changes: ## stream-metadata-go 0.4.3 (2023-06-28) Changes: - Add support for Hyper-V images ## stream-metadata-go 0.4.2 (2023-06-01) Changes: - Drop support for Go 1.17 - Add release notes doc ## stream-metadata-go 0.4.1 (2023-01-30) Changes: - Add support for Secure Execution ## stream-metadata-go 0.4.0 (2022-08-11) - Drop vendored dependencies - Drop support for Go 1.15 and 1.16 - Fix tests ## stream-metadata-go 0.3.0 (2022-04-15) - Switch KubeVirt image struct from `SingleImage` to new `ContainerImage` - Add `ContainerImage.DigestRef` field so we can record both the recommended pullspec and one that includes the digest ## stream-metadata-go 0.2.1 (2022-04-08) - Add support for VirtualBox images ## stream-metadata-go 0.2.0 (2022-04-05) - Rename `RegionObject`/`RegionImage` to `SingleObject`/`SingleImage`; add compatibility aliases - Drop `KubeVirtContainerDisk` types in favor of generic ones ## stream-metadata-go 0.1.8 (2022-03-15) - Add support for KubeVirt images ## stream-metadata-go 0.1.7 (2022-01-25) - Fix Windows build by dropping renameio dependency ## stream-metadata-go 0.1.6 (2021-11-29) - Add support for Nutanix images ## stream-metadata-go 0.1.5 (2021-11-02) - Add support for IBMCloud/PowerVS images - Add `GcpImage.Release` field in stream metadata - Drop `omitempty` from mandatory GcpImage fields ## stream-metadata-go 0.1.4 (2021-10-06) - Make `Artifact.Signature` `omitempty` ## stream-metadata-go 0.1.3 (2021-09-16) - Add `Metadata.Generator` field ## stream-metadata-go 0.1.2 (2021-09-15) - Add support for Alibaba Cloud (`aliyun`) cloud images ## stream-metadata-go 0.1.1 (2021-07-20) - Add support for Azure Stack images ## stream-metadata-go 0.1.0 (2021-04-26) - Initial release stream-metadata-go-0.4.3/example/000077500000000000000000000000001444712103700166305ustar00rootroot00000000000000stream-metadata-go-0.4.3/example/example.go000066400000000000000000000033111444712103700206100ustar00rootroot00000000000000// Package main contains an example use of this library; it // prints the current Fedora CoreOS EC2(AWS) x86_64 AMI in the // us-east-2 region. package main import ( "fmt" "os" "github.com/coreos/stream-metadata-go/fedoracoreos" "github.com/coreos/stream-metadata-go/stream" ) const ( targetArch = "x86_64" region = "us-east-2" ) func downloadISO(fcosstable stream.Stream) error { iso, err := fcosstable.QueryDisk(targetArch, "metal", "iso") if err != nil { return err } fmt.Printf("Downloading %s\n", iso.Location) path, err := iso.Download(".") if err != nil { return fmt.Errorf("Failed to download %s: %w", iso.Location, err) } fmt.Printf("Downloaded %s\n", path) return nil } func printAMI(fcosstable stream.Stream) error { arch, ok := fcosstable.Architectures[targetArch] if !ok { return fmt.Errorf("No %s architecture in stream", targetArch) } awsimages := arch.Images.Aws if awsimages == nil { return fmt.Errorf("No %s AWS images in stream", targetArch) } var regionVal stream.SingleImage if regionVal, ok = awsimages.Regions[region]; !ok { return fmt.Errorf("No %s AWS images in region %s", targetArch, region) } fmt.Printf("%s\n", regionVal.Image) return nil } func run() error { if len(os.Args) != 2 { return fmt.Errorf("usage: example aws-ami|download-iso") } arg := os.Args[1] fcosstable, err := fedoracoreos.FetchStream(fedoracoreos.StreamStable) if err != nil { return err } if arg == "aws-ami" { return printAMI(*fcosstable) } else if arg == "download-iso" { return downloadISO(*fcosstable) } else { return fmt.Errorf("invalid operation %s", arg) } } func main() { if err := run(); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } } stream-metadata-go-0.4.3/fedoracoreos/000077500000000000000000000000001444712103700176505ustar00rootroot00000000000000stream-metadata-go-0.4.3/fedoracoreos/fcos.go000066400000000000000000000025571444712103700211420ustar00rootroot00000000000000// Package fedoracoreos contains APIs defining well-known // streams for Fedora CoreOS and a method to retrieve // the URL for a stream endpoint. package fedoracoreos import ( "encoding/json" "fmt" "io" "net/http" "net/url" "github.com/coreos/stream-metadata-go/fedoracoreos/internals" "github.com/coreos/stream-metadata-go/stream" ) const ( // StreamStable is the default stream StreamStable = "stable" // StreamTesting is what is intended to land in stable StreamTesting = "testing" // StreamNext usually tracks the next Fedora major version StreamNext = "next" ) // GetStreamURL returns the URL for the given stream func GetStreamURL(stream string) url.URL { u := internals.GetBaseURL() u.Path = fmt.Sprintf("streams/%s.json", stream) return u } func getStream(u url.URL) (*stream.Stream, error) { resp, err := http.Get(u.String()) if err != nil { return nil, err } body, err := io.ReadAll(resp.Body) resp.Body.Close() if err != nil { return nil, err } var s stream.Stream err = json.Unmarshal(body, &s) if err != nil { return nil, err } return &s, nil } // FetchStream fetches and parses stream metadata for a stream func FetchStream(streamName string) (*stream.Stream, error) { u := GetStreamURL(streamName) s, err := getStream(u) if err != nil { return nil, fmt.Errorf("failed to fetch stream %s: %w", streamName, err) } return s, nil } stream-metadata-go-0.4.3/fedoracoreos/fcos_test.go000066400000000000000000000003471444712103700221740ustar00rootroot00000000000000package fedoracoreos import "testing" func TestGetStreamURL(t *testing.T) { u := GetStreamURL(StreamStable) if u.String() != "https://builds.coreos.fedoraproject.org/streams/stable.json" { t.Fatalf("Invalid stream url") } } stream-metadata-go-0.4.3/fedoracoreos/internals/000077500000000000000000000000001444712103700216475ustar00rootroot00000000000000stream-metadata-go-0.4.3/fedoracoreos/internals/fcosinternals.go000066400000000000000000000016221444712103700250510ustar00rootroot00000000000000// Package internals contains functions for accessing // the underlying "releases" and coreos-assembler builds // backing streams. General user code should avoid // this package and use streams. package internals import ( "fmt" "net/url" ) // GetBaseURL returns the base URL func GetBaseURL() url.URL { return url.URL{ Scheme: "https", Host: "builds.coreos.fedoraproject.org", } } // GetReleaseIndexURL returns the URL for the release index of a given stream. // Avoid this unless you have a specific need to test a specific release. func GetReleaseIndexURL(stream string) url.URL { u := GetBaseURL() u.Path = fmt.Sprintf("prod/streams/%s/releases.json", stream) return u } // GetCosaBuild returns the coreos-assembler build URL func GetCosaBuild(stream, buildID, arch string) url.URL { u := GetBaseURL() u.Path = fmt.Sprintf("prod/streams/%s/builds/%s/%s/", stream, buildID, arch) return u } stream-metadata-go-0.4.3/go.mod000066400000000000000000000003641444712103700163060ustar00rootroot00000000000000module github.com/coreos/stream-metadata-go go 1.18 require github.com/stretchr/testify v1.8.4 require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) stream-metadata-go-0.4.3/go.sum000066400000000000000000000015611444712103700163330ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= stream-metadata-go-0.4.3/release/000077500000000000000000000000001444712103700166155ustar00rootroot00000000000000stream-metadata-go-0.4.3/release/fixtures/000077500000000000000000000000001444712103700204665ustar00rootroot00000000000000stream-metadata-go-0.4.3/release/fixtures/fcos-release.json000066400000000000000000000305471444712103700237420ustar00rootroot00000000000000{ "release": "33.20201201.3.0", "stream": "stable", "architectures": { "x86_64": { "media": { "aliyun": { "artifacts": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aliyun.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aliyun.x86_64.qcow2.xz.sig", "sha256": "34f3bfd55b0c29804dc2dcace9a671c28b976b62e82e5c42651fd50cf5be4920" } } } }, "aws": { "artifacts": { "vmdk.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aws.x86_64.vmdk.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aws.x86_64.vmdk.xz.sig", "sha256": "5719f3ece03294ae64c0a8b0b1ddbb58f2d932a5923ece043f8446114f9e564a" } } }, "images": { "us-east-1": { "image": "ami-037a0ba6d14ca2e05" }, "me-south-1": { "image": "ami-08830d7d8bf851531" }, "us-east-2": { "image": "ami-091b0dbc05fe2dc06" }, "ca-central-1": { "image": "ami-0d371d51950767885" }, "us-west-2": { "image": "ami-071f6f91a3d8715d7" }, "us-west-1": { "image": "ami-0f775df0ac05d0de6" }, "eu-west-2": { "image": "ami-0b28ffc2766f88e01" }, "eu-west-3": { "image": "ami-0fe2197196b3ca15c" }, "eu-south-1": { "image": "ami-0da68c04abc8a25f2" }, "eu-central-1": { "image": "ami-069b9a4f891c19440" }, "eu-west-1": { "image": "ami-016a154c559c3b81a" }, "eu-north-1": { "image": "ami-0a278fa12694ed1a5" }, "ap-east-1": { "image": "ami-0cb22a422870c3b7f" }, "ap-south-1": { "image": "ami-09de6e47b22138992" }, "ap-northeast-1": { "image": "ami-0370b4b5b620d53b0" }, "af-south-1": { "image": "ami-0bd959051ff340868" }, "ap-northeast-2": { "image": "ami-09d33644806aa7550" }, "ap-southeast-2": { "image": "ami-01e3071d351c82174" }, "ap-southeast-1": { "image": "ami-059b22e3f95e447b8" }, "sa-east-1": { "image": "ami-075fedcd8c24239bc" } } }, "azure": { "artifacts": { "vhd.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-azure.x86_64.vhd.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-azure.x86_64.vhd.xz.sig", "sha256": "7d62c3d06b738268a65d3cd047a87e66b1a04c51b0088a11c87b7b27d224ece3" } } } }, "digitalocean": { "artifacts": { "qcow2.gz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-digitalocean.x86_64.qcow2.gz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-digitalocean.x86_64.qcow2.gz.sig", "sha256": "2b9c851edbc9227fec489cd736df2db11b96df76f82c135675d91103f62ad07b" } } } }, "exoscale": { "artifacts": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-exoscale.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-exoscale.x86_64.qcow2.xz.sig", "sha256": "52342742531ad3b49b4f7727208aeed98ae917ff496cdbb32c08ba4c17c39da5" } } } }, "gcp": { "artifacts": { "tar.gz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-gcp.x86_64.tar.gz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-gcp.x86_64.tar.gz.sig", "sha256": "515b2e42b35a15d30ba770db2e896d161baea5801cc27874c8c8f06e43ce1de7" } } }, "image": { "project": "fedora-coreos-cloud", "family": "fedora-coreos-stable", "name": "fedora-coreos-33-20201201-3-0-gcp-x86-64" } }, "ibmcloud": { "artifacts": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-ibmcloud.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-ibmcloud.x86_64.qcow2.xz.sig", "sha256": "d74829e99bd29464a21e4879d0000b15e4afa944cfed0b5d8ae0b7d8931b6758" } } } }, "metal": { "artifacts": { "raw.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal.x86_64.raw.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal.x86_64.raw.xz.sig", "sha256": "2848b111a6917455686f38a3ce64d2321c33809b9cf796c5f6804b1c02d79d9d" } }, "4k.raw.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal4k.x86_64.raw.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal4k.x86_64.raw.xz.sig", "sha256": "45621b66ee3db98e3515d334f70e095ef58e03d20d77ae5b55668b421372b6ae" } }, "iso": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live.x86_64.iso", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live.x86_64.iso.sig", "sha256": "2f62f8f4813bbf584945052d54746cb83101b2c643705a33711ae26fce15fcba" } }, "pxe": { "kernel": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-kernel-x86_64", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-kernel-x86_64.sig", "sha256": "d6bddcc1cc8f2642b11f38ca4602573211171814a53ab57c2655853008167407" }, "initramfs": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-initramfs.x86_64.img", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-initramfs.x86_64.img.sig", "sha256": "0872233b1af67b728201b121434e8f990e339cebb85a19b4011b7a94fc83f8c3" }, "rootfs": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-rootfs.x86_64.img", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-rootfs.x86_64.img.sig", "sha256": "64306ff0a5f20f4c897a2c20dbbe6764b300df85fa90f3b3f400dc8d80b11495" } } } }, "openstack": { "artifacts": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-openstack.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-openstack.x86_64.qcow2.xz.sig", "sha256": "2be55c5aa1f53eb9a869826dacbab75706ee6bd59185b935ac9be546cc132a85" } } } }, "kubevirt": { "artifacts": { "ociarchive": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-kubevirt.x86_64.ociarchive", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-kubevirt.x86_64.ociarchive.sig", "sha256": "2be55c5aa1f53eb9a869826dacbab75706ee6bd59185b935ac9be546cc132a85" } } }, "image": { "image": "quay.io/openshift-release-dev/rhcos@sha256:67a81539946ec0397196c145394553b8e0241acf27b14ae9de43bc56e167f773" } }, "qemu": { "artifacts": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-qemu.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-qemu.x86_64.qcow2.xz.sig", "sha256": "a7e93e32665086d4a07a14dbe6c125177402f04603fc5bb575035028701afa5b" } } } }, "vmware": { "artifacts": { "ova": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vmware.x86_64.ova", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vmware.x86_64.ova.sig", "sha256": "f800c4cfd53ce2586e101d065eacb3c44082db936af777a71678d9c22d83934c" } } } }, "vultr": { "artifacts": { "raw.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vultr.x86_64.raw.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vultr.x86_64.raw.xz.sig", "sha256": "33ac69ed5fbf3ea6e0a6292894a07491c4b17987323986343ce49109f5f5df7e" } } } } }, "commit": "cad80088392fe43bd3cadf0481c3267f199afa7d9f83bc03937ffdbf5ebbc6da" } } } stream-metadata-go-0.4.3/release/fixtures/fcos-releases.json000066400000000000000000000215221444712103700241160ustar00rootroot00000000000000{ "note": "For use only by Fedora CoreOS internal tooling. All other applications should obtain release info from stream metadata endpoints.", "releases": [ { "commits": [ { "architecture": "x86_64", "checksum": "113aa27efe1bbcf6324af7423f64ef7deb0acbf21b928faec84bf66a60a5c933" } ], "version": "31.20200108.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200108.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "f480038412cba26ab010d2cd5a09ddec736204a6e9faa8370edaa943cf33c932" } ], "version": "31.20200113.3.1", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200113.3.1/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "093f7da6ffa161ae1648a05be9c55f758258ab97b55c628bea5259f6ac6e370e" } ], "version": "31.20200118.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200118.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "2ba7bb9678d86fc469f1920a03c270d7057e0b93d06fcd1a437f1f79bdc26d83" } ], "version": "31.20200127.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200127.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "4ea6beed22d0adc4599452de85820f6e157ac1750e688d062bfedc765b193505" } ], "version": "31.20200210.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200210.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "3477082298eb5e2213433415c78f0919a991b40e62726b8fde434d244c1ec1b6" } ], "version": "31.20200223.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200223.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "436592e6eb93e899bebab8dbd17514c85be683390ef8bbce8c6d96069ce4c543" } ], "version": "31.20200310.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200310.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "9b322b9cead87ebf80881b75560e481b6e5a26966814b01bf0c12b61fa363708" } ], "version": "31.20200323.3.2", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200323.3.2/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "89e17cc21b6aa3bea8959d1e6957fda157168d57ba6805d8a36142184edc2901" } ], "version": "31.20200407.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200407.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "b3fc3a3e8513d7e424d0ced1e2517484cb766d238951f2fdec3da2fed3522efb" } ], "version": "31.20200420.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200420.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "01f074cc6cd88d8d2b43f821da692f2367c101eb4377802cb35092bde0ef02f7" } ], "version": "31.20200505.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200505.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "967b7b8d624e6d10ff51c2e81ef198fae966c567ac2e9b479771c693d0987949" } ], "version": "31.20200517.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200517.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "b51037798e93e5aae5123633fb596c80ddf30302b5110b0581900dbc5b2f0d24" } ], "version": "32.20200601.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200601.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "abb4b978999bd689ff36114e99c737be16026bc154a4428d4c84a340758c5b01" } ], "version": "32.20200615.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200615.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "6df95bdb2fe2d36e091d4d18e3844fa84ce4b80ea3bd0947db5d7a286ff41890" } ], "version": "32.20200629.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200629.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "a3b08ee51b1d950afd9d0d73f32d5424ad52c7703a6b5830e0dc11c3a682d869" } ], "version": "32.20200715.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200715.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "2579b41aa614c3a40b9e24ff0b9dd288f99222dc3ed3a527ef0d8e8667196ff5" } ], "version": "32.20200726.3.1", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200726.3.1/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "902c88022e834fb7998140734fae01b75f78b80f63364e9c5309d62d9a260b7c" } ], "version": "32.20200809.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200809.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "321d73d8865b2899510461cf16c4c2adb60e70031898c8d89e10eed2ac0e438a" } ], "version": "32.20200824.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200824.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "b53de8b03134c5e6b683b5ea471888e9e1b193781794f01b9ed5865b57f35d57" } ], "version": "32.20200907.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200907.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "5090d96f4faf090c90c5f4ebf6c3cdab458acc89f2ba08d1ff704744a143b7e6" } ], "version": "32.20200923.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200923.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "64bb377ae7e6949c26cfe819f3f0bd517596d461e437f2f6e9f1f3c24376fd30" } ], "version": "32.20201004.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20201004.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "a6f3e91ad6e0b8e132769c1694ed9b747a339c04e4e6256fce3afd81c85e1f1f" } ], "version": "32.20201018.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20201018.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "318de830c2f30a97333cd43aa1d500a46ccfedcb2de70a04d0c48228944346da" } ], "version": "32.20201104.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20201104.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "cad80088392fe43bd3cadf0481c3267f199afa7d9f83bc03937ffdbf5ebbc6da" } ], "version": "33.20201201.3.0", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/release.json" }, { "commits": [ { "architecture": "x86_64", "checksum": "a64854cbcec13e1c3b3ccbfd3802e377e23c0c136d384c32736addf77e0e2a03" } ], "version": "33.20201214.3.1", "metadata": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201214.3.1/release.json" } ], "metadata": { "last-modified": "2021-01-05T10:15:52Z" }, "stream": "stable" } stream-metadata-go-0.4.3/release/release.go000066400000000000000000000113751444712103700205730ustar00rootroot00000000000000// Package release contains APIs for interacting with a // particular "release". Avoid this unless you are sure // you need it. It's expected that CoreOS users interact // with streams instead. package release import ( relrhcos "github.com/coreos/stream-metadata-go/release/rhcos" ) // Index models the release index: // https://github.com/coreos/fedora-coreos-tracker/tree/main/metadata/release-index type Index struct { Note string `json:"note"` // used to note to users not to consume the release metadata index Releases []IndexRelease `json:"releases"` Metadata Metadata `json:"metadata"` Stream string `json:"stream"` } // IndexRelease is a "release pointer" from a release index type IndexRelease struct { Commits []IndexReleaseCommit `json:"commits"` Version string `json:"version"` MetadataURL string `json:"metadata"` } // IndexReleaseCommit describes an ostree commit plus architecture type IndexReleaseCommit struct { Architecture string `json:"architecture"` Checksum string `json:"checksum"` } // Release contains details from release.json type Release struct { Release string `json:"release"` Stream string `json:"stream"` Metadata Metadata `json:"metadata"` Architectures map[string]Arch `json:"architectures"` } // Metadata is common metadata that contains last-modified type Metadata struct { LastModified string `json:"last-modified"` } // Arch release details type Arch struct { Commit string `json:"commit"` Media Media `json:"media"` RHELCoreOSExtensions *relrhcos.Extensions `json:"rhel-coreos-extensions,omitempty"` } // Media contains release details for various platforms type Media struct { Aliyun *PlatformAliyun `json:"aliyun"` Aws *PlatformAws `json:"aws"` Azure *PlatformBase `json:"azure"` AzureStack *PlatformBase `json:"azurestack"` Digitalocean *PlatformBase `json:"digitalocean"` Exoscale *PlatformBase `json:"exoscale"` Gcp *PlatformGcp `json:"gcp"` HyperV *PlatformBase `json:"hyperv"` Ibmcloud *PlatformIBMCloud `json:"ibmcloud"` KubeVirt *PlatformKubeVirt `json:"kubevirt"` Metal *PlatformBase `json:"metal"` Nutanix *PlatformBase `json:"nutanix"` Openstack *PlatformBase `json:"openstack"` PowerVS *PlatformIBMCloud `json:"powervs"` Qemu *PlatformBase `json:"qemu"` QemuSecex *PlatformBase `json:"qemu-secex"` VirtualBox *PlatformBase `json:"virtualbox"` Vmware *PlatformBase `json:"vmware"` Vultr *PlatformBase `json:"vultr"` } // PlatformBase with no cloud images type PlatformBase struct { Artifacts map[string]ImageFormat `json:"artifacts"` } // PlatformAliyun contains Aliyun image information type PlatformAliyun struct { PlatformBase Images map[string]CloudImage `json:"images"` } // PlatformAws contains AWS image information type PlatformAws struct { PlatformBase Images map[string]CloudImage `json:"images"` } // PlatformGcp GCP image detail type PlatformGcp struct { PlatformBase Image *GcpImage `json:"image"` } // PlatformIBMCloud IBMCloud/PowerVS image detail type PlatformIBMCloud struct { PlatformBase Images map[string]IBMCloudImage `json:"images"` } // PlatformKubeVirt containerDisk metadata type PlatformKubeVirt struct { PlatformBase Image *ContainerImage `json:"image"` } // 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"` } // CloudImage generic image detail type CloudImage struct { Image string `json:"image"` } // ContainerImage represents a tagged container image type ContainerImage struct { // Preferred way to reference the image, which might be by tag or digest Image string `json:"image"` DigestRef string `json:"digest-ref"` } // GcpImage represents a GCP cloud image type GcpImage struct { Project string `json:"project"` Family string `json:"family,omitempty"` Name string `json:"name"` } // IBMCloudImage represents an IBMCloud/PowerVS cloud object - which is an ova image for PowerVS and a qcow for IBMCloud in the cloud object storage bucket type IBMCloudImage struct { Object string `json:"object"` Bucket string `json:"bucket"` Url string `json:"url"` } stream-metadata-go-0.4.3/release/release_test.go000066400000000000000000000032221444712103700216220ustar00rootroot00000000000000package release import ( "encoding/json" "os" "testing" "time" "github.com/coreos/stream-metadata-go/stream" "github.com/stretchr/testify/assert" ) const ( usEast2Ami = "ami-091b0dbc05fe2dc06" ) func TestParseFCR(t *testing.T) { d, err := os.ReadFile("fixtures/fcos-release.json") assert.Nil(t, err) release := Release{} err = json.Unmarshal(d, &release) assert.Nil(t, err) assert.Equal(t, release.Stream, "stable") assert.Equal(t, release.Architectures["x86_64"].Media.Aws.Images["us-east-2"].Image, usEast2Ami) } func TestParseFCRIndex(t *testing.T) { d, err := os.ReadFile("fixtures/fcos-releases.json") assert.Nil(t, err) idx := Index{} err = json.Unmarshal(d, &idx) assert.Nil(t, err) assert.Equal(t, idx.Stream, "stable") release := idx.Releases[0] assert.Equal(t, release.Version, "31.20200108.3.0") assert.Equal(t, release.Commits[0].Architecture, "x86_64") assert.Equal(t, release.Commits[0].Checksum, "113aa27efe1bbcf6324af7423f64ef7deb0acbf21b928faec84bf66a60a5c933") } func TestTranslate(t *testing.T) { d, err := os.ReadFile("fixtures/fcos-release.json") assert.Nil(t, err) rel := Release{} err = json.Unmarshal(d, &rel) assert.Nil(t, err) arches := rel.ToStreamArchitectures() st := stream.Stream{ Stream: rel.Stream, Metadata: stream.Metadata{LastModified: time.Now().UTC().Format(time.RFC3339)}, Architectures: arches, } assert.Equal(t, st.Architectures["x86_64"].Images.Aws.Regions["us-east-2"].Image, usEast2Ami) // KubeVirt assert.Equal(t, st.Architectures["x86_64"].Images.KubeVirt.Image, "quay.io/openshift-release-dev/rhcos@sha256:67a81539946ec0397196c145394553b8e0241acf27b14ae9de43bc56e167f773") } stream-metadata-go-0.4.3/release/rhcos/000077500000000000000000000000001444712103700177335ustar00rootroot00000000000000stream-metadata-go-0.4.3/release/rhcos/rhcos.go000066400000000000000000000007211444712103700214000ustar00rootroot00000000000000package rhcos // Extensions is data specific to Red Hat Enterprise Linux CoreOS type Extensions struct { AzureDisk *AzureDisk `json:"azure-disk,omitempty"` } // AzureDisk represents an Azure cloud image. type AzureDisk struct { // 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"` } stream-metadata-go-0.4.3/release/translate.go000066400000000000000000000175201444712103700211460ustar00rootroot00000000000000package release import ( "github.com/coreos/stream-metadata-go/stream" "github.com/coreos/stream-metadata-go/stream/rhcos" ) func mapArtifact(ra *Artifact) *stream.Artifact { if ra == nil { return nil } return &stream.Artifact{ Location: ra.Location, Signature: ra.Signature, Sha256: ra.Sha256, UncompressedSha256: ra.UncompressedSha256, } } func mapFormats(m map[string]ImageFormat) map[string]stream.ImageFormat { r := make(map[string]stream.ImageFormat) for k, v := range m { r[k] = stream.ImageFormat{ Disk: mapArtifact(v.Disk), Kernel: mapArtifact(v.Kernel), Initramfs: mapArtifact(v.Initramfs), Rootfs: mapArtifact(v.Rootfs), } } return r } // Convert a release architecture to a stream architecture func (releaseArch *Arch) toStreamArch(rel *Release) stream.Arch { artifacts := make(map[string]stream.PlatformArtifacts) cloudImages := stream.Images{} var rhcosExt *rhcos.Extensions relRHCOSExt := releaseArch.RHELCoreOSExtensions if relRHCOSExt != nil { rhcosExt = &rhcos.Extensions{} } if releaseArch.Media.Aliyun != nil { artifacts["aliyun"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Aliyun.Artifacts), } aliyunImages := stream.ReplicatedImage{ Regions: make(map[string]stream.SingleImage), } if releaseArch.Media.Aliyun.Images != nil { for region, image := range releaseArch.Media.Aliyun.Images { si := stream.SingleImage{Release: rel.Release, Image: image.Image} aliyunImages.Regions[region] = si } cloudImages.Aliyun = &aliyunImages } } if releaseArch.Media.Aws != nil { artifacts["aws"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Aws.Artifacts), } awsAmis := stream.ReplicatedImage{ Regions: make(map[string]stream.SingleImage), } if releaseArch.Media.Aws.Images != nil { for region, ami := range releaseArch.Media.Aws.Images { si := stream.SingleImage{Release: rel.Release, Image: ami.Image} awsAmis.Regions[region] = si } cloudImages.Aws = &awsAmis } } if releaseArch.Media.Azure != nil { artifacts["azure"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Azure.Artifacts), } if relRHCOSExt != nil { az := relRHCOSExt.AzureDisk if az != nil { rhcosExt.AzureDisk = &rhcos.AzureDisk{ Release: rel.Release, URL: az.URL, } } } // In the future this is where we'd also add FCOS Marketplace data. // See https://github.com/coreos/stream-metadata-go/issues/13 } if releaseArch.Media.AzureStack != nil { artifacts["azurestack"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.AzureStack.Artifacts), } } if releaseArch.Media.Digitalocean != nil { artifacts["digitalocean"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Digitalocean.Artifacts), } /* We're producing artifacts but they're not yet available in DigitalOcean as distribution images. digitalOceanImage := stream.CloudImage{Image: fmt.Sprintf("fedora-coreos-%s", Stream)} cloudImages.Digitalocean = &digitalOceanImage */ } if releaseArch.Media.Exoscale != nil { artifacts["exoscale"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Exoscale.Artifacts), } } if releaseArch.Media.Gcp != nil { artifacts["gcp"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Gcp.Artifacts), } if releaseArch.Media.Gcp.Image != nil { cloudImages.Gcp = &stream.GcpImage{ Release: rel.Release, Name: releaseArch.Media.Gcp.Image.Name, Family: releaseArch.Media.Gcp.Image.Family, Project: releaseArch.Media.Gcp.Image.Project, } } } if releaseArch.Media.HyperV != nil { artifacts["hyperv"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.HyperV.Artifacts), } } if releaseArch.Media.Ibmcloud != nil { artifacts["ibmcloud"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Ibmcloud.Artifacts), } ibmcloudObjects := stream.ReplicatedObject{ Regions: make(map[string]stream.SingleObject), } if releaseArch.Media.Ibmcloud.Images != nil { for region, object := range releaseArch.Media.Ibmcloud.Images { so := stream.SingleObject{ Release: rel.Release, Object: object.Object, Bucket: object.Bucket, Url: object.Url, } ibmcloudObjects.Regions[region] = so } cloudImages.Ibmcloud = &ibmcloudObjects } } if releaseArch.Media.KubeVirt != nil { artifacts["kubevirt"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.KubeVirt.Artifacts), } if releaseArch.Media.KubeVirt.Image != nil { cloudImages.KubeVirt = &stream.ContainerImage{ Release: rel.Release, Image: releaseArch.Media.KubeVirt.Image.Image, DigestRef: releaseArch.Media.KubeVirt.Image.DigestRef, } } } if releaseArch.Media.Metal != nil { artifacts["metal"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Metal.Artifacts), } } if releaseArch.Media.Nutanix != nil { artifacts["nutanix"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Nutanix.Artifacts), } } if releaseArch.Media.Openstack != nil { artifacts["openstack"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Openstack.Artifacts), } } // if releaseArch.Media.Packet != nil { // packet := StreamMediaDetails{ // Release: rel.Release, // Formats: releaseArch.Media.Packet.Artifacts, // } // artifacts.Packet = &packet // packetImage := StreamCloudImage{Image: fmt.Sprintf("fedora_coreos_%s", rel.Stream)} // cloudImages.Packet = &packetImage // } if releaseArch.Media.PowerVS != nil { artifacts["powervs"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.PowerVS.Artifacts), } powervsObjects := stream.ReplicatedObject{ Regions: make(map[string]stream.SingleObject), } if releaseArch.Media.PowerVS.Images != nil { for region, object := range releaseArch.Media.PowerVS.Images { so := stream.SingleObject{ Release: rel.Release, Object: object.Object, Bucket: object.Bucket, Url: object.Url, } powervsObjects.Regions[region] = so } cloudImages.PowerVS = &powervsObjects } } if releaseArch.Media.Qemu != nil { artifacts["qemu"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Qemu.Artifacts), } } if releaseArch.Media.QemuSecex != nil { artifacts["qemu-secex"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.QemuSecex.Artifacts), } } if releaseArch.Media.VirtualBox != nil { artifacts["virtualbox"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.VirtualBox.Artifacts), } } if releaseArch.Media.Vmware != nil { artifacts["vmware"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Vmware.Artifacts), } } if releaseArch.Media.Vultr != nil { artifacts["vultr"] = stream.PlatformArtifacts{ Release: rel.Release, Formats: mapFormats(releaseArch.Media.Vultr.Artifacts), } } return stream.Arch{ Artifacts: artifacts, Images: cloudImages, RHELCoreOSExtensions: rhcosExt, } } // ToStreamArchitectures converts a release to a stream func (rel *Release) ToStreamArchitectures() map[string]stream.Arch { streamArch := make(map[string]stream.Arch) for arch, releaseArch := range rel.Architectures { streamArch[arch] = releaseArch.toStreamArch(rel) } return streamArch } stream-metadata-go-0.4.3/stream/000077500000000000000000000000001444712103700164705ustar00rootroot00000000000000stream-metadata-go-0.4.3/stream/artifact_utils.go000066400000000000000000000043361444712103700220420ustar00rootroot00000000000000package stream import ( "crypto/sha256" "fmt" "io" "net/http" "net/url" "os" "path" "path/filepath" ) // Fetch an artifact, validating its checksum. If applicable, // the artifact will not be decompressed. Does not // validate GPG signature. func (a *Artifact) Fetch(w io.Writer) error { resp, err := http.Get(a.Location) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("%s returned status: %s", a.Location, resp.Status) } hasher := sha256.New() reader := io.TeeReader(resp.Body, hasher) _, err = io.Copy(w, reader) if err != nil { return err } // Validate sha256 checksum foundChecksum := fmt.Sprintf("%x", hasher.Sum(nil)) if a.Sha256 != foundChecksum { return fmt.Errorf("checksum mismatch for %s; expected=%s found=%s", a.Location, a.Sha256, foundChecksum) } return nil } // Name returns the "basename" of the artifact, i.e. the contents // after the last `/`. This can be useful when downloading to a file. func (a *Artifact) Name() (string, error) { loc, err := url.Parse(a.Location) if err != nil { return "", fmt.Errorf("failed to parse artifact url: %w", err) } // Note this one uses `path` since even on Windows URLs have forward slashes. return path.Base(loc.Path), nil } // Download fetches the specified artifact and saves it to the target // directory. The full file path will be returned as a string. // If the target file path exists, it will be overwritten. // If the download fails, the temporary file will be deleted. func (a *Artifact) Download(destdir string) (string, error) { name, err := a.Name() if err != nil { return "", err } destfile := filepath.Join(destdir, name) w, err := os.CreateTemp(destdir, ".coreos-artifact-") if err != nil { return "", err } finalized := false defer func() { if !finalized { // Ignore an error to unlink _ = os.Remove(w.Name()) } }() if err := a.Fetch(w); err != nil { return "", err } if err := w.Sync(); err != nil { return "", err } if err := w.Chmod(0644); err != nil { return "", err } if err := w.Close(); err != nil { return "", err } if err := os.Rename(w.Name(), destfile); err != nil { return "", err } finalized = true return destfile, nil } stream-metadata-go-0.4.3/stream/fixtures/000077500000000000000000000000001444712103700203415ustar00rootroot00000000000000stream-metadata-go-0.4.3/stream/fixtures/fcos-stream.json000066400000000000000000000536201444712103700234650ustar00rootroot00000000000000{ "stream": "stable", "metadata": { "last-modified": "2020-12-17T14:18:43Z", "generator": "fedora-coreos-stream-generator v0" }, "architectures": { "x86_64": { "artifacts": { "aliyun": { "release": "33.20201201.3.0", "formats": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aliyun.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aliyun.x86_64.qcow2.xz.sig", "sha256": "34f3bfd55b0c29804dc2dcace9a671c28b976b62e82e5c42651fd50cf5be4920" } } } }, "aws": { "release": "33.20201201.3.0", "formats": { "vmdk.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aws.x86_64.vmdk.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-aws.x86_64.vmdk.xz.sig", "sha256": "5719f3ece03294ae64c0a8b0b1ddbb58f2d932a5923ece043f8446114f9e564a" } } } }, "azure": { "release": "33.20201201.3.0", "formats": { "vhd.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-azure.x86_64.vhd.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-azure.x86_64.vhd.xz.sig", "sha256": "7d62c3d06b738268a65d3cd047a87e66b1a04c51b0088a11c87b7b27d224ece3" } } } }, "digitalocean": { "release": "33.20201201.3.0", "formats": { "qcow2.gz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-digitalocean.x86_64.qcow2.gz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-digitalocean.x86_64.qcow2.gz.sig", "sha256": "2b9c851edbc9227fec489cd736df2db11b96df76f82c135675d91103f62ad07b" } } } }, "exoscale": { "release": "33.20201201.3.0", "formats": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-exoscale.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-exoscale.x86_64.qcow2.xz.sig", "sha256": "52342742531ad3b49b4f7727208aeed98ae917ff496cdbb32c08ba4c17c39da5" } } } }, "gcp": { "release": "33.20201201.3.0", "formats": { "tar.gz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-gcp.x86_64.tar.gz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-gcp.x86_64.tar.gz.sig", "sha256": "515b2e42b35a15d30ba770db2e896d161baea5801cc27874c8c8f06e43ce1de7" } } } }, "ibmcloud": { "release": "33.20201201.3.0", "formats": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-ibmcloud.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-ibmcloud.x86_64.qcow2.xz.sig", "sha256": "d74829e99bd29464a21e4879d0000b15e4afa944cfed0b5d8ae0b7d8931b6758" } } } }, "metal": { "release": "33.20201201.3.0", "formats": { "4k.raw.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal4k.x86_64.raw.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal4k.x86_64.raw.xz.sig", "sha256": "45621b66ee3db98e3515d334f70e095ef58e03d20d77ae5b55668b421372b6ae" } }, "iso": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live.x86_64.iso", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live.x86_64.iso.sig", "sha256": "2f62f8f4813bbf584945052d54746cb83101b2c643705a33711ae26fce15fcba" } }, "pxe": { "kernel": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-kernel-x86_64", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-kernel-x86_64.sig", "sha256": "d6bddcc1cc8f2642b11f38ca4602573211171814a53ab57c2655853008167407" }, "initramfs": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-initramfs.x86_64.img", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-initramfs.x86_64.img.sig", "sha256": "0872233b1af67b728201b121434e8f990e339cebb85a19b4011b7a94fc83f8c3" }, "rootfs": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-rootfs.x86_64.img", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live-rootfs.x86_64.img.sig", "sha256": "64306ff0a5f20f4c897a2c20dbbe6764b300df85fa90f3b3f400dc8d80b11495" } }, "raw.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal.x86_64.raw.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-metal.x86_64.raw.xz.sig", "sha256": "2848b111a6917455686f38a3ce64d2321c33809b9cf796c5f6804b1c02d79d9d" } } } }, "openstack": { "release": "33.20201201.3.0", "formats": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-openstack.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-openstack.x86_64.qcow2.xz.sig", "sha256": "2be55c5aa1f53eb9a869826dacbab75706ee6bd59185b935ac9be546cc132a85" } } } }, "kubevirt": { "release": "33.20201201.3.0", "formats": { "ociarchive": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-kubevirt.x86_64.ociarchive", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-kubevirt.x86_64.ociarchive.sig", "sha256": "2be55c5aa1f53eb9a869826dacbab75706ee6bd59185b935ac9be546cc132a85" } } } }, "qemu": { "release": "33.20201201.3.0", "formats": { "qcow2.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-qemu.x86_64.qcow2.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-qemu.x86_64.qcow2.xz.sig", "sha256": "a7e93e32665086d4a07a14dbe6c125177402f04603fc5bb575035028701afa5b" } } } }, "vmware": { "release": "33.20201201.3.0", "formats": { "ova": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vmware.x86_64.ova", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vmware.x86_64.ova.sig", "sha256": "f800c4cfd53ce2586e101d065eacb3c44082db936af777a71678d9c22d83934c" } } } }, "vultr": { "release": "33.20201201.3.0", "formats": { "raw.xz": { "disk": { "location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vultr.x86_64.raw.xz", "signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-vultr.x86_64.raw.xz.sig", "sha256": "33ac69ed5fbf3ea6e0a6292894a07491c4b17987323986343ce49109f5f5df7e" } } } } }, "images": { "aliyun": { "regions": { "ap-northeast-1": { "release": "33.20201201.3.0", "image": "m-6wecinpim9haf6ws23r2" }, "ap-south-1": { "release": "33.20201201.3.0", "image": "m-a2d7rl7sf9fhtgs2fqqp" }, "ap-southeast-1": { "release": "33.20201201.3.0", "image": "m-t4n8qbyvu3hm6s9aibgt" }, "ap-southeast-2": { "release": "33.20201201.3.0", "image": "m-p0wdy2bd65vy5foymbyn" }, "ap-southeast-3": { "release": "33.20201201.3.0", "image": "m-8pse8lfxohn0pv9w3s4d" }, "ap-southeast-5": { "release": "33.20201201.3.0", "image": "m-k1a07hbstlz2nrcpw97q" }, "cn-beijing": { "release": "33.20201201.3.0", "image": "m-2ze3iqjpvxst7wgwkd6m" }, "cn-chengdu": { "release": "33.20201201.3.0", "image": "m-2vcftvw1c1pd1iq1tr8u" }, "cn-guangzhou": { "release": "33.20201201.3.0", "image": "m-7xvfemexpzytrtonb04q" }, "cn-hangzhou": { "release": "33.20201201.3.0", "image": "m-bp1b29lcl6hx1cu1kknx" }, "cn-heyuan": { "release": "33.20201201.3.0", "image": "m-f8z2s66jqkz6lqbdrmxk" }, "cn-hongkong": { "release": "33.20201201.3.0", "image": "m-j6cci77g4mwv4dgw9pf4" }, "cn-huhehaote": { "release": "33.20201201.3.0", "image": "m-hp3hsaie1sgguc3mf9ww" }, "cn-nanjing": { "release": "33.20201201.3.0", "image": "m-gc79us39ybgr6oxs4lgu" }, "cn-qingdao": { "release": "33.20201201.3.0", "image": "m-m5e71jt32enfboyrdf5h" }, "cn-shanghai": { "release": "33.20201201.3.0", "image": "m-uf6caftakxqri7bf37vf" }, "cn-shenzhen": { "release": "33.20201201.3.0", "image": "m-wz97oj9dscgdiypk45e8" }, "cn-wulanchabu": { "release": "33.20201201.3.0", "image": "m-0jl5ejm6aczs1n9a7z0z" }, "cn-zhangjiakou": { "release": "33.20201201.3.0", "image": "m-8vbg3hxkp6i5zpdklate" }, "eu-central-1": { "release": "33.20201201.3.0", "image": "m-gw885u4yrv9yo6t3u1ge" }, "eu-west-1": { "release": "33.20201201.3.0", "image": "m-d7o3sn3qtbax50wep8ra" }, "me-east-1": { "release": "33.20201201.3.0", "image": "m-eb3bcaf3xkdl8bbesjp4" }, "us-east-1": { "release": "33.20201201.3.0", "image": "m-0xie8imuezj6of7584wz" }, "us-west-1": { "release": "33.20201201.3.0", "image": "m-rj93zda388u2hepp7edc" } } }, "aws": { "regions": { "af-south-1": { "release": "33.20201201.3.0", "image": "ami-0bd959051ff340868" }, "ap-east-1": { "release": "33.20201201.3.0", "image": "ami-0cb22a422870c3b7f" }, "ap-northeast-1": { "release": "33.20201201.3.0", "image": "ami-0370b4b5b620d53b0" }, "ap-northeast-2": { "release": "33.20201201.3.0", "image": "ami-09d33644806aa7550" }, "ap-south-1": { "release": "33.20201201.3.0", "image": "ami-09de6e47b22138992" }, "ap-southeast-1": { "release": "33.20201201.3.0", "image": "ami-059b22e3f95e447b8" }, "ap-southeast-2": { "release": "33.20201201.3.0", "image": "ami-01e3071d351c82174" }, "ca-central-1": { "release": "33.20201201.3.0", "image": "ami-0d371d51950767885" }, "eu-central-1": { "release": "33.20201201.3.0", "image": "ami-069b9a4f891c19440" }, "eu-north-1": { "release": "33.20201201.3.0", "image": "ami-0a278fa12694ed1a5" }, "eu-south-1": { "release": "33.20201201.3.0", "image": "ami-0da68c04abc8a25f2" }, "eu-west-1": { "release": "33.20201201.3.0", "image": "ami-016a154c559c3b81a" }, "eu-west-2": { "release": "33.20201201.3.0", "image": "ami-0b28ffc2766f88e01" }, "eu-west-3": { "release": "33.20201201.3.0", "image": "ami-0fe2197196b3ca15c" }, "me-south-1": { "release": "33.20201201.3.0", "image": "ami-08830d7d8bf851531" }, "sa-east-1": { "release": "33.20201201.3.0", "image": "ami-075fedcd8c24239bc" }, "us-east-1": { "release": "33.20201201.3.0", "image": "ami-037a0ba6d14ca2e05" }, "us-east-2": { "release": "33.20201201.3.0", "image": "ami-091b0dbc05fe2dc06" }, "us-west-1": { "release": "33.20201201.3.0", "image": "ami-0f775df0ac05d0de6" }, "us-west-2": { "release": "33.20201201.3.0", "image": "ami-071f6f91a3d8715d7" } } }, "gcp": { "release": "33.20201201.3.0", "project": "fedora-coreos-cloud", "family": "fedora-coreos-stable", "name": "fedora-coreos-33-20201201-3-0-gcp-x86-64" }, "kubevirt": { "release": "33.20211201.3.0", "image": "quay.io/openshift-release-dev/rhcos:latest", "digest-ref": "quay.io/openshift-release-dev/rhcos@sha256:67a81539946ec0397196c145394553b8e0241acf27b14ae9de43bc56e167f773" } } } } } stream-metadata-go-0.4.3/stream/rhcos/000077500000000000000000000000001444712103700176065ustar00rootroot00000000000000stream-metadata-go-0.4.3/stream/rhcos/rhcos.go000066400000000000000000000012311444712103700212500ustar00rootroot00000000000000package 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"` } stream-metadata-go-0.4.3/stream/stream.go000066400000000000000000000074201444712103700203150ustar00rootroot00000000000000// 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"` Generator string `json:"generator,omitempty"` } // 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,omitempty"` Sha256 string `json:"sha256"` UncompressedSha256 string `json:"uncompressed-sha256,omitempty"` } // Images contains images available in cloud providers type Images struct { Aliyun *ReplicatedImage `json:"aliyun,omitempty"` Aws *AwsImage `json:"aws,omitempty"` Gcp *GcpImage `json:"gcp,omitempty"` Ibmcloud *ReplicatedObject `json:"ibmcloud,omitempty"` KubeVirt *ContainerImage `json:"kubevirt,omitempty"` PowerVS *ReplicatedObject `json:"powervs,omitempty"` } // ReplicatedImage represents an image in all regions of an AWS-like cloud type ReplicatedImage struct { Regions map[string]SingleImage `json:"regions,omitempty"` } // SingleImage represents a globally-accessible image or an image in a // single region of an AWS-like cloud type SingleImage struct { Release string `json:"release"` Image string `json:"image"` } // ContainerImage represents a tagged container image type ContainerImage struct { Release string `json:"release"` // Preferred way to reference the image, which might be by tag or digest Image string `json:"image"` DigestRef string `json:"digest-ref"` } // AwsImage is a typedef for backwards compatibility. type AwsImage = ReplicatedImage // AwsRegionImage is a typedef for backwards compatibility. type AwsRegionImage = SingleImage // RegionImage is a typedef for backwards compatibility. type RegionImage = SingleImage // GcpImage represents a GCP cloud image type GcpImage struct { Release string `json:"release"` Project string `json:"project"` Family string `json:"family,omitempty"` Name string `json:"name"` } // ReplicatedObject represents an object in all regions of an IBMCloud-like // cloud type ReplicatedObject struct { Regions map[string]SingleObject `json:"regions,omitempty"` } // SingleObject represents a globally-accessible cloud storage object, or // an object in a single region of an IBMCloud-like cloud type SingleObject struct { Release string `json:"release"` Object string `json:"object"` Bucket string `json:"bucket"` Url string `json:"url"` } // RegionObject is a typedef for backwards compatibility. type RegionObject = SingleObject stream-metadata-go-0.4.3/stream/stream_test.go000066400000000000000000000060121444712103700213500ustar00rootroot00000000000000package stream import ( "encoding/json" "os" "testing" "github.com/stretchr/testify/assert" ) func TestParseFCS(t *testing.T) { d, err := os.ReadFile("fixtures/fcos-stream.json") assert.Nil(t, err) stream := Stream{} err = json.Unmarshal(d, &stream) assert.Nil(t, err) assert.Equal(t, stream.Stream, "stable") assert.Equal(t, stream.Architectures["x86_64"].Artifacts["metal"].Formats["raw.xz"].Disk.Sha256, "2848b111a6917455686f38a3ce64d2321c33809b9cf796c5f6804b1c02d79d9d") assert.Equal(t, stream.Architectures["x86_64"].Images.Aws.Regions["us-east-2"].Image, "ami-091b0dbc05fe2dc06") assert.Equal(t, stream.Architectures["x86_64"].Images.Aliyun.Regions["eu-west-1"].Image, "m-d7o3sn3qtbax50wep8ra") ami, err := stream.GetAMI("x86_64", "us-east-2") assert.Nil(t, err) assert.Equal(t, ami, "ami-091b0dbc05fe2dc06") aliyunImage, err := stream.GetAliyunImage("x86_64", "eu-west-1") assert.Nil(t, err) assert.Equal(t, aliyunImage, "m-d7o3sn3qtbax50wep8ra") assert.Equal(t, "stable/x86_64", stream.FormatPrefix("x86_64")) // I hope I live to see the day when we might change this code to test for success and not error _, err = stream.GetAMI("x86_64", "mars-1") assert.NotNil(t, err) assert.Contains(t, err.Error(), "stable/x86_64: No AWS images in region mars-1") _, err = stream.GetAMI("aarch64", "us-east-2") assert.NotNil(t, err) assert.Contains(t, err.Error(), "stream:stable does not have architecture 'aarch64'") _, err = stream.GetAliyunImage("x86_64", "us-midwest-1") assert.NotNil(t, err) assert.Contains(t, err.Error(), "stable/x86_64: No Aliyun images in region us-midwest-1") _, err = stream.GetAliyunImage("aarch64", "us-east-2") assert.NotNil(t, err) assert.Contains(t, err.Error(), "stream:stable does not have architecture 'aarch64'") a, err := stream.QueryDisk("x86_64", "metal", "iso") assert.Nil(t, err) assert.Equal(t, a.Location, "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/33.20201201.3.0/x86_64/fedora-coreos-33.20201201.3.0-live.x86_64.iso") name, err := a.Name() assert.Nil(t, err) assert.Equal(t, name, "fedora-coreos-33.20201201.3.0-live.x86_64.iso") _, err = stream.QueryDisk("x86_64", "metal", "nosuchthing") assert.NotNil(t, err) assert.Contains(t, err.Error(), "disk not found") _, err = stream.QueryDisk("x86_64", "mysterious-obelisk", "rune") assert.NotNil(t, err) assert.Contains(t, err.Error(), "artifact 'mysterious-obelisk' not found") _, err = stream.QueryDisk("nonarch", "", "nosuchthing") assert.NotNil(t, err) assert.Contains(t, err.Error(), "does not have architecture 'nonarch'") assert.Equal(t, stream.Architectures["x86_64"].Images.KubeVirt, &ContainerImage{ Release: "33.20211201.3.0", Image: "quay.io/openshift-release-dev/rhcos:latest", DigestRef: "quay.io/openshift-release-dev/rhcos@sha256:67a81539946ec0397196c145394553b8e0241acf27b14ae9de43bc56e167f773", }) assert.Equal(t, stream.Architectures["x86_64"].Artifacts["kubevirt"].Formats["ociarchive"].Disk.Sha256, "2be55c5aa1f53eb9a869826dacbab75706ee6bd59185b935ac9be546cc132a85") } stream-metadata-go-0.4.3/stream/stream_utils.go000066400000000000000000000061471444712103700215420ustar00rootroot00000000000000package 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 } // GetAliyunRegionImage returns the release data (Image ID and release ID) for a particular // architecture and region. func (st *Stream) GetAliyunRegionImage(archname, region string) (*SingleImage, error) { starch, err := st.GetArchitecture(archname) if err != nil { return nil, err } aliyunimages := starch.Images.Aliyun if aliyunimages == nil { return nil, fmt.Errorf("%s: No Aliyun images", st.FormatPrefix(archname)) } var regionVal SingleImage var ok bool if regionVal, ok = aliyunimages.Regions[region]; !ok { return nil, fmt.Errorf("%s: No Aliyun images in region %s", st.FormatPrefix(archname), region) } return ®ionVal, nil } // GetAliyunImage returns the Aliyun image for a particular architecture and region. func (st *Stream) GetAliyunImage(archname, region string) (string, error) { regionVal, err := st.GetAliyunRegionImage(archname, region) if err != nil { return "", err } return regionVal.Image, nil } // GetAwsRegionImage returns the release data (AMI and release ID) for a particular // architecture and region. func (st *Stream) GetAwsRegionImage(archname, region string) (*SingleImage, 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 SingleImage 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 } // QueryDisk finds the singleton disk artifact for a given format and architecture. func (st *Stream) QueryDisk(architectureName, artifactName, formatName string) (*Artifact, error) { arch, err := st.GetArchitecture(architectureName) if err != nil { return nil, err } artifacts := arch.Artifacts[artifactName] if artifacts.Release == "" { return nil, fmt.Errorf("%s: artifact '%s' not found", st.FormatPrefix(architectureName), artifactName) } format := artifacts.Formats[formatName] if format.Disk == nil { return nil, fmt.Errorf("%s: artifact '%s' format '%s' disk not found", st.FormatPrefix(architectureName), artifactName, formatName) } return format.Disk, nil } stream-metadata-go-0.4.3/tag_release.sh000077500000000000000000000010741444712103700200110ustar00rootroot00000000000000#!/usr/bin/env bash # Maintained in https://github.com/coreos/repo-templates # Do not edit downstream. set -e [ $# == 2 ] || { echo "usage: $0 " && exit 1; } VER=$1 COMMIT=$2 [[ "${VER}" =~ ^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(-.+)?$ ]] || { echo "malformed version: \"${VER}\"" exit 2 } [[ "${COMMIT}" =~ ^[[:xdigit:]]+$ ]] || { echo "malformed commit id: \"${COMMIT}\"" exit 3 } if [ -f Makefile ]; then make else ./build fi git tag --sign --message "stream-metadata-go ${VER}" "${VER}" "${COMMIT}" git verify-tag --verbose "${VER}"