-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rhcos: implement image discovery for new pipeline
RHCOS has moved over to the 2.0 pipeline which has a nicer discovery mechanism for images. This uses that new pipeline to fetch the latest QCOW images for the latest build. Unfortunately, there is no "latest" alias anymore, so the installer has to fetch resources from the Internet before it can prompt the user. This will go away once the installer starts pinning to a specific RHCOS release.
- Loading branch information
Showing
4 changed files
with
148 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package rhcos | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
const ( | ||
// DefaultChannel is the default RHCOS channel for the cluster. | ||
DefaultChannel = "maipo" | ||
|
||
baseURL = "https://releases-rhcos.svc.ci.openshift.org/storage/releases" | ||
) | ||
|
||
type metadata struct { | ||
AMIs []struct { | ||
HVM string `json:"hvm"` | ||
Name string `json:"name"` | ||
} `json:"amis"` | ||
Images struct { | ||
QEMU struct { | ||
Path string `json:"path"` | ||
SHA256 string `json:"sha256"` | ||
} `json:"qemu"` | ||
} `json:"images"` | ||
OSTreeVersion string `json:"ostree-version"` | ||
} | ||
|
||
func fetchLatestMetadata(ctx context.Context, channel string) (metadata, error) { | ||
build, err := fetchLatestBuild(ctx, channel) | ||
if err != nil { | ||
return metadata{}, errors.Wrap(err, "failed to fetch latest build") | ||
} | ||
|
||
url := fmt.Sprintf("%s/%s/%s/meta.json", baseURL, channel, build) | ||
logrus.Debugf("Fetching RHCOS metadata from %q", url) | ||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
return metadata{}, errors.Wrap(err, "failed to build request") | ||
} | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req.WithContext(ctx)) | ||
if err != nil { | ||
return metadata{}, errors.Wrap(err, "failed to fetch metadata") | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return metadata{}, errors.Errorf("incorrect HTTP response (%s)", resp.Status) | ||
} | ||
|
||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return metadata{}, errors.Wrap(err, "failed to read HTTP response") | ||
} | ||
|
||
var meta metadata | ||
if err := json.Unmarshal(body, &meta); err != nil { | ||
return meta, errors.Wrap(err, "failed to parse HTTP response") | ||
} | ||
|
||
return meta, nil | ||
} | ||
|
||
func fetchLatestBuild(ctx context.Context, channel string) (string, error) { | ||
url := fmt.Sprintf("%s/%s/builds.json", baseURL, channel) | ||
logrus.Debugf("Fetching RHCOS builds from %q", url) | ||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to build request") | ||
} | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req.WithContext(ctx)) | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to fetch builds") | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return "", errors.Errorf("incorrect HTTP response (%s)", resp.Status) | ||
} | ||
|
||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to read HTTP response") | ||
} | ||
|
||
var builds struct { | ||
Builds []string `json:"builds"` | ||
} | ||
if err := json.Unmarshal(body, &builds); err != nil { | ||
return "", errors.Wrap(err, "failed to parse HTTP response") | ||
} | ||
|
||
if len(builds.Builds) == 0 { | ||
return "", errors.Errorf("no builds found") | ||
} | ||
|
||
return builds.Builds[0], nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package rhcos | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
// QEMU fetches the URL of the latest Red Hat CoreOS release. | ||
func QEMU(ctx context.Context, channel string) (string, error) { | ||
meta, err := fetchLatestMetadata(ctx, channel) | ||
if err != nil { | ||
return "", errors.Wrap(err, "failed to fetch RHCOS metadata") | ||
} | ||
|
||
return fmt.Sprintf("%s/%s/%s/%s", baseURL, channel, meta.OSTreeVersion, meta.Images.QEMU.Path), nil | ||
} |