1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
package sources
import (
"errors"
"fmt"
"io"
"net/http"
"net/url"
"path/filepath"
"regexp"
"strings"
"github.com/lxc/distrobuilder/shared"
)
type apertis struct {
common
}
// Run downloads the tarball and unpacks it.
func (s *apertis) Run() error {
release := s.definition.Image.Release
exactRelease := release
// https://images.apertis.org/daily/v2020dev0/20190830.0/amd64/minimal/ospack_v2020dev0-amd64-minimal_20190830.0.tar.gz
baseURL := fmt.Sprintf("%s/%s/%s",
s.definition.Source.URL, s.definition.Source.Variant, release)
var (
resp *http.Response
err error
)
err = shared.Retry(func() error {
resp, err = s.client.Head(baseURL)
if err != nil {
return fmt.Errorf("Failed to HEAD %q: %w", baseURL, err)
}
return nil
}, 3)
if err != nil {
return err
}
if resp.StatusCode == http.StatusNotFound {
// Possibly, release is a specific release (18.12.0 instead of 18.12). Lets trim the prefix and continue.
re := regexp.MustCompile(`\.\d+$`)
release = strings.TrimSuffix(release, re.FindString(release))
baseURL = fmt.Sprintf("%s/%s/%s",
s.definition.Source.URL, s.definition.Source.Variant, release)
} else {
exactRelease, err = s.getLatestRelease(baseURL, release)
if err != nil {
return fmt.Errorf("Failed to get latest release: %w", err)
}
}
baseURL = fmt.Sprintf("%s/%s/%s/%s/",
baseURL, exactRelease, s.definition.Image.ArchitectureMapped, s.definition.Image.Variant)
fname := fmt.Sprintf("ospack_%s-%s-%s_%s.tar.gz",
release, s.definition.Image.ArchitectureMapped, s.definition.Image.Variant, exactRelease)
url, err := url.Parse(baseURL)
if err != nil {
return fmt.Errorf("Failed to parse %q: %w", baseURL, err)
}
// Force gpg checks when using http
if url.Scheme != "https" {
return errors.New("Only HTTPS server is supported")
}
fpath, err := s.DownloadHash(s.definition.Image, baseURL+fname, "", nil)
if err != nil {
return fmt.Errorf("Failed to download %q: %w", baseURL+fname, err)
}
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")
// Unpack
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
}
return nil
}
func (s *apertis) getLatestRelease(baseURL, release string) (string, error) {
var (
resp *http.Response
err error
)
err = shared.Retry(func() error {
resp, err = s.client.Get(baseURL)
if err != nil {
return fmt.Errorf("Failed to GET %q: %w", baseURL, err)
}
return nil
}, 3)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("Failed to ready body: %w", err)
}
regex := regexp.MustCompile(fmt.Sprintf(">(%s\\.\\d+)/<", release))
releases := regex.FindAllStringSubmatch(string(body), -1)
if len(releases) > 0 {
return releases[len(releases)-1][1], nil
}
return "", nil
}
|