Merge pull request #105 from monstermunchkin/fix/various

definition: Add Source.SkipVerification
This commit is contained in:
Stéphane Graber 2018-07-03 01:22:30 -04:00 committed by GitHub
commit 375d44646d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 82 additions and 48 deletions

View File

@ -42,15 +42,16 @@ type DefinitionImage struct {
// A DefinitionSource specifies the download type and location // A DefinitionSource specifies the download type and location
type DefinitionSource struct { type DefinitionSource struct {
Downloader string `yaml:"downloader"` Downloader string `yaml:"downloader"`
URL string `yaml:"url,omitempty"` URL string `yaml:"url,omitempty"`
Keys []string `yaml:"keys,omitempty"` Keys []string `yaml:"keys,omitempty"`
Keyserver string `yaml:"keyserver,omitempty"` Keyserver string `yaml:"keyserver,omitempty"`
Variant string `yaml:"variant,omitempty"` Variant string `yaml:"variant,omitempty"`
Suite string `yaml:"suite,omitempty"` Suite string `yaml:"suite,omitempty"`
SameAs string `yaml:"same_as,omitempty"` SameAs string `yaml:"same_as,omitempty"`
AptSources string `yaml:"apt_sources,omitempty"` AptSources string `yaml:"apt_sources,omitempty"`
IgnoreRelease bool `yaml:"ignore_release,omitempty"` IgnoreRelease bool `yaml:"ignore_release,omitempty"`
SkipVerification bool `yaml:"skip_verification,omitempty"`
} }
// A DefinitionTargetLXCConfig represents the config part of the metadata. // A DefinitionTargetLXCConfig represents the config part of the metadata.
@ -114,7 +115,7 @@ type Definition struct {
} }
// SetValue writes the provided value to a field represented by the yaml tag 'key'. // SetValue writes the provided value to a field represented by the yaml tag 'key'.
func (d *Definition) SetValue(key string, value interface{}) error { func (d *Definition) SetValue(key string, value string) error {
// Walk through the definition and find the field with the given key // Walk through the definition and find the field with the given key
field, err := getFieldByTag(reflect.ValueOf(d).Elem(), reflect.TypeOf(d).Elem(), key) field, err := getFieldByTag(reflect.ValueOf(d).Elem(), reflect.TypeOf(d).Elem(), key)
if err != nil { if err != nil {
@ -126,22 +127,29 @@ func (d *Definition) SetValue(key string, value interface{}) error {
return fmt.Errorf("Cannot set value for %s", key) return fmt.Errorf("Cannot set value for %s", key)
} }
if reflect.TypeOf(value).Kind() != field.Kind() { switch field.Kind() {
return fmt.Errorf("Cannot assign %s value to %s",
reflect.TypeOf(value).Kind(), field.Kind())
}
switch reflect.TypeOf(value).Kind() {
case reflect.Bool: case reflect.Bool:
field.SetBool(value.(bool)) v, err := strconv.ParseBool(value)
if err != nil {
return err
}
field.SetBool(v)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
field.SetInt(value.(int64)) v, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return err
}
field.SetInt(v)
case reflect.String: case reflect.String:
field.SetString(value.(string)) field.SetString(value)
case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
field.SetUint(value.(uint64)) v, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return err
}
field.SetUint(v)
default: default:
return fmt.Errorf("Unknown value type %s", reflect.TypeOf(value).Kind()) return fmt.Errorf("Unsupported type '%s'", field.Kind())
} }
return nil return nil

View File

@ -234,9 +234,10 @@ func TestDefinitionSetValue(t *testing.T) {
Release: "artful", Release: "artful",
}, },
Source: DefinitionSource{ Source: DefinitionSource{
Downloader: "debootstrap", Downloader: "debootstrap",
URL: "https://ubuntu.com", URL: "https://ubuntu.com",
Keys: []string{"0xCODE"}, Keys: []string{"0xCODE"},
IgnoreRelease: true,
}, },
Packages: DefinitionPackages{ Packages: DefinitionPackages{
Manager: "apt", Manager: "apt",
@ -277,7 +278,15 @@ func TestDefinitionSetValue(t *testing.T) {
// Nonsense // Nonsense
err = d.SetValue("image", "[foo: bar]") err = d.SetValue("image", "[foo: bar]")
if err == nil || err.Error() != "Cannot assign string value to struct" { if err == nil || err.Error() != "Unsupported type 'struct'" {
t.Fatal("Expected unsupported assignment") t.Fatal("Expected unsupported assignment")
} }
err = d.SetValue("source.ignore_release", "true")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if !d.Source.IgnoreRelease {
t.Fatalf("Expected '%v', got '%v'", true, d.Source.IgnoreRelease)
}
} }

View File

@ -56,17 +56,22 @@ func (s *AlpineLinuxHTTP) Run(definition shared.Definition, rootfsDir string) er
return err return err
} }
if url.Scheme != "https" && len(definition.Source.Keys) == 0 { if !definition.Source.SkipVerification && url.Scheme != "https" &&
len(definition.Source.Keys) == 0 {
return errors.New("GPG keys are required if downloading from HTTP") return errors.New("GPG keys are required if downloading from HTTP")
} }
err = shared.DownloadSha256(tarball, tarball+".sha256") if definition.Source.SkipVerification {
err = shared.DownloadSha256(tarball, "")
} else {
err = shared.DownloadSha256(tarball, tarball+".sha256")
}
if err != nil { if err != nil {
return err return err
} }
// Force gpg checks when using http // Force gpg checks when using http
if url.Scheme != "https" { if !definition.Source.SkipVerification && url.Scheme != "https" {
shared.DownloadSha256(tarball+".asc", "") shared.DownloadSha256(tarball+".asc", "")
valid, err := shared.VerifyFile( valid, err := shared.VerifyFile(
filepath.Join(os.TempDir(), fname), filepath.Join(os.TempDir(), fname),

View File

@ -33,7 +33,8 @@ func (s *ArchLinuxHTTP) Run(definition shared.Definition, rootfsDir string) erro
return err return err
} }
if url.Scheme != "https" && len(definition.Source.Keys) == 0 { if !definition.Source.SkipVerification && url.Scheme != "https" &&
len(definition.Source.Keys) == 0 {
return errors.New("GPG keys are required if downloading from HTTP") return errors.New("GPG keys are required if downloading from HTTP")
} }
@ -43,7 +44,7 @@ func (s *ArchLinuxHTTP) Run(definition shared.Definition, rootfsDir string) erro
} }
// Force gpg checks when using http // Force gpg checks when using http
if url.Scheme != "https" { if !definition.Source.SkipVerification && url.Scheme != "https" {
shared.DownloadSha256(tarball+".sig", "") shared.DownloadSha256(tarball+".sig", "")
valid, err := shared.VerifyFile( valid, err := shared.VerifyFile(

View File

@ -45,21 +45,23 @@ func (s *CentOSHTTP) Run(definition shared.Definition, rootfsDir string) error {
} }
checksumFile := "" checksumFile := ""
// Force gpg checks when using http if !definition.Source.SkipVerification {
if url.Scheme != "https" { // Force gpg checks when using http
if len(definition.Source.Keys) == 0 { if url.Scheme != "https" {
return errors.New("GPG keys are required if downloading from HTTP") if len(definition.Source.Keys) == 0 {
} return errors.New("GPG keys are required if downloading from HTTP")
}
checksumFile = "sha256sum.txt.asc" checksumFile = "sha256sum.txt"
shared.DownloadSha256(baseURL+checksumFile, "") shared.DownloadSha256(baseURL+checksumFile, "")
valid, err := shared.VerifyFile(filepath.Join(os.TempDir(), checksumFile), "", valid, err := shared.VerifyFile(filepath.Join(os.TempDir(), checksumFile), "",
definition.Source.Keys, definition.Source.Keyserver) definition.Source.Keys, definition.Source.Keyserver)
if err != nil { if err != nil {
return err return err
} }
if !valid { if !valid {
return errors.New("Failed to verify tarball") return errors.New("Failed to verify tarball")
}
} }
} }

View File

@ -33,6 +33,10 @@ func (s *Debootstrap) Run(definition shared.Definition, rootfsDir string) error
args = append(args, "--arch", definition.Image.ArchitectureMapped) args = append(args, "--arch", definition.Image.ArchitectureMapped)
} }
if definition.Source.SkipVerification {
args = append(args, "--no-check-gpg")
}
if len(definition.Source.Keys) > 0 { if len(definition.Source.Keys) > 0 {
keyring, err := shared.CreateGPGKeyring(definition.Source.Keyserver, definition.Source.Keys) keyring, err := shared.CreateGPGKeyring(definition.Source.Keyserver, definition.Source.Keys)
if err != nil { if err != nil {

View File

@ -44,17 +44,22 @@ func (s *GentooHTTP) Run(definition shared.Definition, rootfsDir string) error {
return err return err
} }
if url.Scheme != "https" && len(definition.Source.Keys) == 0 { if !definition.Source.SkipVerification && url.Scheme != "https" &&
len(definition.Source.Keys) == 0 {
return errors.New("GPG keys are required if downloading from HTTP") return errors.New("GPG keys are required if downloading from HTTP")
} }
err = shared.DownloadSha512(tarball, tarball+".DIGESTS") if definition.Source.SkipVerification {
err = shared.DownloadSha512(tarball, "")
} else {
err = shared.DownloadSha512(tarball, tarball+".DIGESTS")
}
if err != nil { if err != nil {
return err return err
} }
// Force gpg checks when using http // Force gpg checks when using http
if url.Scheme != "https" { if !definition.Source.SkipVerification && url.Scheme != "https" {
shared.DownloadSha512(tarball+".DIGESTS.asc", "") shared.DownloadSha512(tarball+".DIGESTS.asc", "")
valid, err := shared.VerifyFile( valid, err := shared.VerifyFile(
filepath.Join(os.TempDir(), fname+".DIGESTS.asc"), filepath.Join(os.TempDir(), fname+".DIGESTS.asc"),

View File

@ -51,7 +51,7 @@ func (s *UbuntuHTTP) Run(definition shared.Definition, rootfsDir string) error {
checksumFile := "" checksumFile := ""
// Force gpg checks when using http // Force gpg checks when using http
if url.Scheme != "https" { if !definition.Source.SkipVerification && url.Scheme != "https" {
if len(definition.Source.Keys) == 0 { if len(definition.Source.Keys) == 0 {
return errors.New("GPG keys are required if downloading from HTTP") return errors.New("GPG keys are required if downloading from HTTP")
} }