summaryrefslogtreecommitdiff
path: root/pkg/machine/fedora.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/machine/fedora.go')
-rw-r--r--pkg/machine/fedora.go122
1 files changed, 122 insertions, 0 deletions
diff --git a/pkg/machine/fedora.go b/pkg/machine/fedora.go
new file mode 100644
index 000000000..cd713dde7
--- /dev/null
+++ b/pkg/machine/fedora.go
@@ -0,0 +1,122 @@
+// +build amd64 arm64
+
+package machine
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "os"
+ "path/filepath"
+ "regexp"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ githubURL = "http://github.com/fedora-cloud/docker-brew-fedora/"
+)
+
+type FedoraDownload struct {
+ Download
+}
+
+func NewFedoraDownloader(vmType, vmName, releaseStream string) (DistributionDownload, error) {
+ imageName, downloadURL, size, err := getFedoraDownload(releaseStream)
+ if err != nil {
+ return nil, err
+ }
+
+ dataDir, err := GetDataDir(vmType)
+ if err != nil {
+ return nil, err
+ }
+
+ f := FedoraDownload{
+ Download: Download{
+ Arch: getFcosArch(),
+ Artifact: artifact,
+ Format: Format,
+ ImageName: imageName,
+ LocalPath: filepath.Join(dataDir, imageName),
+ URL: downloadURL,
+ VMName: vmName,
+ Size: size,
+ },
+ }
+ f.Download.LocalUncompressedFile = f.getLocalUncompressedName()
+ return f, nil
+}
+
+func (f FedoraDownload) Get() *Download {
+ return &f.Download
+}
+
+func (f FedoraDownload) HasUsableCache() (bool, error) {
+ info, err := os.Stat(f.LocalPath)
+ if err != nil {
+ return false, nil
+ }
+ return info.Size() == f.Size, nil
+}
+
+func truncRead(url string) ([]byte, error) {
+ resp, err := http.Get(url)
+ if err != nil {
+ return nil, err
+ }
+
+ defer func() {
+ if err := resp.Body.Close(); err != nil {
+ logrus.Error(err)
+ }
+ }()
+
+ body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 10*1024*1024))
+ if err != nil {
+ return nil, err
+ }
+
+ _, _ = io.Copy(io.Discard, resp.Body)
+
+ return body, nil
+}
+
+func getFedoraDownload(releaseStream string) (string, *url.URL, int64, error) {
+ dirURL := githubURL + "tree/" + releaseStream + "/" + getFcosArch() + "/"
+ body, err := truncRead(dirURL)
+ if err != nil {
+ return "", nil, -1, err
+ }
+
+ rx, err := regexp.Compile(`fedora[^\"]+xz`)
+ if err != nil {
+ return "", nil, -1, err
+ }
+ file := rx.FindString(string(body))
+ if len(file) <= 0 {
+ return "", nil, -1, fmt.Errorf("could not locate Fedora download at %s", dirURL)
+ }
+
+ rawURL := githubURL + "raw/" + releaseStream + "/" + getFcosArch() + "/"
+ newLocation := rawURL + file
+ downloadURL, err := url.Parse(newLocation)
+ if err != nil {
+ return "", nil, -1, errors.Wrapf(err, "invalid URL generated from discovered Fedora file: %s", newLocation)
+ }
+
+ resp, err := http.Head(newLocation)
+ if err != nil {
+ return "", nil, -1, errors.Wrapf(err, "head request failed: %s", newLocation)
+ }
+ _ = resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return "", nil, -1, fmt.Errorf("head request failed [%d] on download: %s", resp.StatusCode, newLocation)
+ }
+
+ return file, downloadURL, resp.ContentLength, nil
+}