From 91598f1fa27148a811e98a40adb596add988c0f4 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Mon, 2 Jul 2018 16:50:33 +0200 Subject: [PATCH 1/2] definition: Fix SetValue function Signed-off-by: Thomas Hipp --- shared/definition.go | 31 +++++++++++++++++++------------ shared/definition_test.go | 17 +++++++++++++---- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/shared/definition.go b/shared/definition.go index 0252a22..bf9c5f8 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -114,7 +114,7 @@ type Definition struct { } // 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 field, err := getFieldByTag(reflect.ValueOf(d).Elem(), reflect.TypeOf(d).Elem(), key) if err != nil { @@ -126,22 +126,29 @@ func (d *Definition) SetValue(key string, value interface{}) error { return fmt.Errorf("Cannot set value for %s", key) } - if reflect.TypeOf(value).Kind() != field.Kind() { - return fmt.Errorf("Cannot assign %s value to %s", - reflect.TypeOf(value).Kind(), field.Kind()) - } - - switch reflect.TypeOf(value).Kind() { + switch field.Kind() { 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: - field.SetInt(value.(int64)) + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return err + } + field.SetInt(v) case reflect.String: - field.SetString(value.(string)) + field.SetString(value) 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: - return fmt.Errorf("Unknown value type %s", reflect.TypeOf(value).Kind()) + return fmt.Errorf("Unsupported type '%s'", field.Kind()) } return nil diff --git a/shared/definition_test.go b/shared/definition_test.go index aa1f085..e078a5a 100644 --- a/shared/definition_test.go +++ b/shared/definition_test.go @@ -234,9 +234,10 @@ func TestDefinitionSetValue(t *testing.T) { Release: "artful", }, Source: DefinitionSource{ - Downloader: "debootstrap", - URL: "https://ubuntu.com", - Keys: []string{"0xCODE"}, + Downloader: "debootstrap", + URL: "https://ubuntu.com", + Keys: []string{"0xCODE"}, + IgnoreRelease: true, }, Packages: DefinitionPackages{ Manager: "apt", @@ -277,7 +278,15 @@ func TestDefinitionSetValue(t *testing.T) { // Nonsense 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") } + + 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) + } } From fb39a671f7657d18815221ef0249855809586dba Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Mon, 2 Jul 2018 17:37:31 +0200 Subject: [PATCH 2/2] definition: Add Source.SkipVerification This allows for the source verification to be skipped if needed. Signed-off-by: Thomas Hipp --- shared/definition.go | 19 ++++++++++--------- sources/alpine-http.go | 11 ++++++++--- sources/archlinux-http.go | 5 +++-- sources/centos-http.go | 30 ++++++++++++++++-------------- sources/debootstrap.go | 4 ++++ sources/gentoo.go | 11 ++++++++--- sources/ubuntu-http.go | 2 +- 7 files changed, 50 insertions(+), 32 deletions(-) diff --git a/shared/definition.go b/shared/definition.go index bf9c5f8..f3b78de 100644 --- a/shared/definition.go +++ b/shared/definition.go @@ -42,15 +42,16 @@ type DefinitionImage struct { // A DefinitionSource specifies the download type and location type DefinitionSource struct { - Downloader string `yaml:"downloader"` - URL string `yaml:"url,omitempty"` - Keys []string `yaml:"keys,omitempty"` - Keyserver string `yaml:"keyserver,omitempty"` - Variant string `yaml:"variant,omitempty"` - Suite string `yaml:"suite,omitempty"` - SameAs string `yaml:"same_as,omitempty"` - AptSources string `yaml:"apt_sources,omitempty"` - IgnoreRelease bool `yaml:"ignore_release,omitempty"` + Downloader string `yaml:"downloader"` + URL string `yaml:"url,omitempty"` + Keys []string `yaml:"keys,omitempty"` + Keyserver string `yaml:"keyserver,omitempty"` + Variant string `yaml:"variant,omitempty"` + Suite string `yaml:"suite,omitempty"` + SameAs string `yaml:"same_as,omitempty"` + AptSources string `yaml:"apt_sources,omitempty"` + IgnoreRelease bool `yaml:"ignore_release,omitempty"` + SkipVerification bool `yaml:"skip_verification,omitempty"` } // A DefinitionTargetLXCConfig represents the config part of the metadata. diff --git a/sources/alpine-http.go b/sources/alpine-http.go index 7fe1736..e19f449 100644 --- a/sources/alpine-http.go +++ b/sources/alpine-http.go @@ -56,17 +56,22 @@ func (s *AlpineLinuxHTTP) Run(definition shared.Definition, rootfsDir string) er 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") } - err = shared.DownloadSha256(tarball, tarball+".sha256") + if definition.Source.SkipVerification { + err = shared.DownloadSha256(tarball, "") + } else { + err = shared.DownloadSha256(tarball, tarball+".sha256") + } if err != nil { return err } // Force gpg checks when using http - if url.Scheme != "https" { + if !definition.Source.SkipVerification && url.Scheme != "https" { shared.DownloadSha256(tarball+".asc", "") valid, err := shared.VerifyFile( filepath.Join(os.TempDir(), fname), diff --git a/sources/archlinux-http.go b/sources/archlinux-http.go index 13b62c0..0f39c1c 100644 --- a/sources/archlinux-http.go +++ b/sources/archlinux-http.go @@ -33,7 +33,8 @@ func (s *ArchLinuxHTTP) Run(definition shared.Definition, rootfsDir string) erro 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") } @@ -43,7 +44,7 @@ func (s *ArchLinuxHTTP) Run(definition shared.Definition, rootfsDir string) erro } // Force gpg checks when using http - if url.Scheme != "https" { + if !definition.Source.SkipVerification && url.Scheme != "https" { shared.DownloadSha256(tarball+".sig", "") valid, err := shared.VerifyFile( diff --git a/sources/centos-http.go b/sources/centos-http.go index ae0fdc9..0b68617 100644 --- a/sources/centos-http.go +++ b/sources/centos-http.go @@ -45,21 +45,23 @@ func (s *CentOSHTTP) Run(definition shared.Definition, rootfsDir string) error { } checksumFile := "" - // Force gpg checks when using http - if url.Scheme != "https" { - if len(definition.Source.Keys) == 0 { - return errors.New("GPG keys are required if downloading from HTTP") - } + if !definition.Source.SkipVerification { + // Force gpg checks when using http + if url.Scheme != "https" { + if len(definition.Source.Keys) == 0 { + return errors.New("GPG keys are required if downloading from HTTP") + } - checksumFile = "sha256sum.txt.asc" - shared.DownloadSha256(baseURL+checksumFile, "") - valid, err := shared.VerifyFile(filepath.Join(os.TempDir(), checksumFile), "", - definition.Source.Keys, definition.Source.Keyserver) - if err != nil { - return err - } - if !valid { - return errors.New("Failed to verify tarball") + checksumFile = "sha256sum.txt" + shared.DownloadSha256(baseURL+checksumFile, "") + valid, err := shared.VerifyFile(filepath.Join(os.TempDir(), checksumFile), "", + definition.Source.Keys, definition.Source.Keyserver) + if err != nil { + return err + } + if !valid { + return errors.New("Failed to verify tarball") + } } } diff --git a/sources/debootstrap.go b/sources/debootstrap.go index 7da85e4..8f77f38 100644 --- a/sources/debootstrap.go +++ b/sources/debootstrap.go @@ -33,6 +33,10 @@ func (s *Debootstrap) Run(definition shared.Definition, rootfsDir string) error args = append(args, "--arch", definition.Image.ArchitectureMapped) } + if definition.Source.SkipVerification { + args = append(args, "--no-check-gpg") + } + if len(definition.Source.Keys) > 0 { keyring, err := shared.CreateGPGKeyring(definition.Source.Keyserver, definition.Source.Keys) if err != nil { diff --git a/sources/gentoo.go b/sources/gentoo.go index 8a85069..2381d34 100644 --- a/sources/gentoo.go +++ b/sources/gentoo.go @@ -44,17 +44,22 @@ func (s *GentooHTTP) Run(definition shared.Definition, rootfsDir string) error { 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") } - err = shared.DownloadSha512(tarball, tarball+".DIGESTS") + if definition.Source.SkipVerification { + err = shared.DownloadSha512(tarball, "") + } else { + err = shared.DownloadSha512(tarball, tarball+".DIGESTS") + } if err != nil { return err } // Force gpg checks when using http - if url.Scheme != "https" { + if !definition.Source.SkipVerification && url.Scheme != "https" { shared.DownloadSha512(tarball+".DIGESTS.asc", "") valid, err := shared.VerifyFile( filepath.Join(os.TempDir(), fname+".DIGESTS.asc"), diff --git a/sources/ubuntu-http.go b/sources/ubuntu-http.go index b875bcd..e843ecc 100644 --- a/sources/ubuntu-http.go +++ b/sources/ubuntu-http.go @@ -51,7 +51,7 @@ func (s *UbuntuHTTP) Run(definition shared.Definition, rootfsDir string) error { checksumFile := "" // Force gpg checks when using http - if url.Scheme != "https" { + if !definition.Source.SkipVerification && url.Scheme != "https" { if len(definition.Source.Keys) == 0 { return errors.New("GPG keys are required if downloading from HTTP") }