mirror of
https://github.com/lxc/distrobuilder.git
synced 2026-02-05 06:45:19 +01:00
VoidLinux uses signify signatures (.sig files), not GPG.
This reverts voidlinux-http.go changes from commit 64b60db9.
Signed-off-by: Chaosoffire <81634128+chaosoffire@users.noreply.github.com>
136 lines
3.2 KiB
Go
136 lines
3.2 KiB
Go
package sources
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/lxc/distrobuilder/shared"
|
|
)
|
|
|
|
type voidlinux struct {
|
|
common
|
|
}
|
|
|
|
// Run downloads a Void Linux rootfs tarball.
|
|
func (s *voidlinux) Run() error {
|
|
baseURL := s.definition.Source.URL
|
|
fname, err := s.getLatestBuild(baseURL, s.definition.Image.ArchitectureMapped, s.definition.Source.Variant)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to get latest build: %w", err)
|
|
}
|
|
|
|
if fname == "" {
|
|
return errors.New("Failed to determine latest build")
|
|
}
|
|
|
|
tarball := fmt.Sprintf("%s/%s", baseURL, fname)
|
|
digests := fmt.Sprintf("%s/sha256sum.txt", baseURL)
|
|
signatures := fmt.Sprintf("%s/sha256sum.sig", baseURL)
|
|
|
|
url, err := url.Parse(tarball)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to parse URL %q: %w", tarball, err)
|
|
}
|
|
|
|
if !s.definition.Source.SkipVerification && url.Scheme != "https" &&
|
|
len(s.definition.Source.Keys) == 0 {
|
|
return errors.New("GPG keys are required if downloading from HTTP")
|
|
}
|
|
|
|
var fpath string
|
|
|
|
if s.definition.Source.SkipVerification {
|
|
fpath, err = s.DownloadHash(s.definition.Image, tarball, "", nil)
|
|
} else {
|
|
fpath, err = s.DownloadHash(s.definition.Image, tarball, digests, sha256.New())
|
|
}
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
|
}
|
|
|
|
// Force gpg checks when using http
|
|
if !s.definition.Source.SkipVerification && url.Scheme != "https" {
|
|
_, err = s.DownloadHash(s.definition.Image, digests, "", nil)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to download %q: %w", digests, err)
|
|
}
|
|
|
|
_, err = s.DownloadHash(s.definition.Image, signatures, "", nil)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to download %q: %w", signatures, err)
|
|
}
|
|
|
|
valid, err := s.VerifyFile(
|
|
filepath.Join(fpath, "sha256sum.txt"),
|
|
filepath.Join(fpath, "sha256sum.sig"))
|
|
if err != nil {
|
|
return fmt.Errorf(`Failed to verify "sha256sum.txt": %w`, err)
|
|
}
|
|
|
|
if !valid {
|
|
return errors.New(`Invalid signature for "sha256sum.txt"`)
|
|
}
|
|
}
|
|
|
|
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", filepath.Join(fpath, fname), err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *voidlinux) getLatestBuild(baseURL, arch, variant 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 read body: %w", err)
|
|
}
|
|
|
|
// Look for .tar.xz
|
|
selector := arch
|
|
if variant != "" {
|
|
selector = fmt.Sprintf("%s-%s", selector, variant)
|
|
}
|
|
|
|
regex := regexp.MustCompile(fmt.Sprintf(">void-%s-ROOTFS-.*.tar.xz<", selector))
|
|
|
|
// Find all rootfs related files
|
|
matches := regex.FindAllString(string(body), -1)
|
|
if len(matches) > 0 {
|
|
// Take the first match since they're all the same anyway
|
|
return strings.Trim(matches[0], "<>"), nil
|
|
}
|
|
|
|
return "", errors.New("Failed to find latest build")
|
|
}
|