mirror of
https://github.com/distribution/distribution.git
synced 2025-09-25 14:18:10 +00:00
Enable configuration of index dependency validation
Enable configuration options that can selectively disable validation that dependencies exist within the registry before the image index is uploaded. This enables sparse indexes, where a registry holds a manifest index that could be signed (so the digest must not change) but does not hold every referenced image in the index. The use case for this is when a registry mirror does not need to mirror all platforms, but does need to maintain the digests of all manifests either because they are signed or because they are pulled by digest. The registry administrator can also select specific image architectures that must exist in the registry, enabling a registry operator to select only the platforms they care about and ensure all image indexes uploaded to the registry are valid for those platforms. Signed-off-by: James Hewitt <james.hewitt@uk.ibm.com>
This commit is contained in:
@@ -181,25 +181,7 @@ type Configuration struct {
|
||||
Proxy Proxy `yaml:"proxy,omitempty"`
|
||||
|
||||
// Validation configures validation options for the registry.
|
||||
Validation struct {
|
||||
// Enabled enables the other options in this section. This field is
|
||||
// deprecated in favor of Disabled.
|
||||
Enabled bool `yaml:"enabled,omitempty"`
|
||||
// Disabled disables the other options in this section.
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
// Manifests configures manifest validation.
|
||||
Manifests struct {
|
||||
// URLs configures validation for URLs in pushed manifests.
|
||||
URLs struct {
|
||||
// Allow specifies regular expressions (https://godoc.org/regexp/syntax)
|
||||
// that URLs in pushed manifests must match.
|
||||
Allow []string `yaml:"allow,omitempty"`
|
||||
// Deny specifies regular expressions (https://godoc.org/regexp/syntax)
|
||||
// that URLs in pushed manifests must not match.
|
||||
Deny []string `yaml:"deny,omitempty"`
|
||||
} `yaml:"urls,omitempty"`
|
||||
} `yaml:"manifests,omitempty"`
|
||||
} `yaml:"validation,omitempty"`
|
||||
Validation Validation `yaml:"validation,omitempty"`
|
||||
|
||||
// Policy configures registry policy options.
|
||||
Policy struct {
|
||||
@@ -366,6 +348,13 @@ type Health struct {
|
||||
} `yaml:"storagedriver,omitempty"`
|
||||
}
|
||||
|
||||
type Platform struct {
|
||||
// Architecture is the architecture for this platform
|
||||
Architecture string `yaml:"architecture,omitempty"`
|
||||
// OS is the operating system for this platform
|
||||
OS string `yaml:"os,omitempty"`
|
||||
}
|
||||
|
||||
// v0_1Configuration is a Version 0.1 Configuration struct
|
||||
// This is currently aliased to Configuration, as it is the current version
|
||||
type v0_1Configuration Configuration
|
||||
@@ -653,6 +642,62 @@ type Proxy struct {
|
||||
TTL *time.Duration `yaml:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
type Validation struct {
|
||||
// Enabled enables the other options in this section. This field is
|
||||
// deprecated in favor of Disabled.
|
||||
Enabled bool `yaml:"enabled,omitempty"`
|
||||
// Disabled disables the other options in this section.
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
// Manifests configures manifest validation.
|
||||
Manifests ValidationManifests `yaml:"manifests,omitempty"`
|
||||
}
|
||||
|
||||
type ValidationManifests struct {
|
||||
// URLs configures validation for URLs in pushed manifests.
|
||||
URLs struct {
|
||||
// Allow specifies regular expressions (https://godoc.org/regexp/syntax)
|
||||
// that URLs in pushed manifests must match.
|
||||
Allow []string `yaml:"allow,omitempty"`
|
||||
// Deny specifies regular expressions (https://godoc.org/regexp/syntax)
|
||||
// that URLs in pushed manifests must not match.
|
||||
Deny []string `yaml:"deny,omitempty"`
|
||||
} `yaml:"urls,omitempty"`
|
||||
// ImageIndexes configures validation of image indexes
|
||||
Indexes ValidationIndexes `yaml:"indexes,omitempty"`
|
||||
}
|
||||
|
||||
type ValidationIndexes struct {
|
||||
// Platforms configures the validation applies to the platform images included in an image index
|
||||
Platforms Platforms `yaml:"platforms"`
|
||||
// PlatformList filters the set of platforms to validate for image existence.
|
||||
PlatformList []Platform `yaml:"platformlist,omitempty"`
|
||||
}
|
||||
|
||||
// Platforms configures the validation applies to the platform images included in an image index
|
||||
// This can be all, none, or list
|
||||
type Platforms string
|
||||
|
||||
// UnmarshalYAML implements the yaml.Umarshaler interface
|
||||
// Unmarshals a string into a Platforms option, lowercasing the string and validating that it represents a
|
||||
// valid option
|
||||
func (platforms *Platforms) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var platformsString string
|
||||
err := unmarshal(&platformsString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
platformsString = strings.ToLower(platformsString)
|
||||
switch platformsString {
|
||||
case "all", "none", "list":
|
||||
default:
|
||||
return fmt.Errorf("invalid platforms option %s Must be one of [all, none, list]", platformsString)
|
||||
}
|
||||
|
||||
*platforms = Platforms(platformsString)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse parses an input configuration yaml document into a Configuration struct
|
||||
// This should generally be capable of handling old configuration format versions
|
||||
//
|
||||
|
@@ -151,6 +151,13 @@ var configStruct = Configuration{
|
||||
ReadTimeout: time.Millisecond * 10,
|
||||
WriteTimeout: time.Millisecond * 10,
|
||||
},
|
||||
Validation: Validation{
|
||||
Manifests: ValidationManifests{
|
||||
Indexes: ValidationIndexes{
|
||||
Platforms: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// configYamlV0_1 is a Version 0.1 yaml document representing configStruct
|
||||
@@ -206,6 +213,10 @@ redis:
|
||||
dialtimeout: 10ms
|
||||
readtimeout: 10ms
|
||||
writetimeout: 10ms
|
||||
validation:
|
||||
manifests:
|
||||
indexes:
|
||||
platforms: none
|
||||
`
|
||||
|
||||
// inmemoryConfigYamlV0_1 is a Version 0.1 yaml document specifying an inmemory
|
||||
@@ -235,6 +246,10 @@ notifications:
|
||||
http:
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
validation:
|
||||
manifests:
|
||||
indexes:
|
||||
platforms: none
|
||||
`
|
||||
|
||||
type ConfigSuite struct {
|
||||
@@ -295,6 +310,7 @@ func (suite *ConfigSuite) TestParseIncomplete() {
|
||||
suite.expectedConfig.Notifications = Notifications{}
|
||||
suite.expectedConfig.HTTP.Headers = nil
|
||||
suite.expectedConfig.Redis = Redis{}
|
||||
suite.expectedConfig.Validation.Manifests.Indexes.Platforms = ""
|
||||
|
||||
// Note: this also tests that REGISTRY_STORAGE and
|
||||
// REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY can be used together
|
||||
@@ -566,5 +582,11 @@ func copyConfig(config Configuration) *Configuration {
|
||||
|
||||
configCopy.Redis = config.Redis
|
||||
|
||||
configCopy.Validation = Validation{
|
||||
Enabled: config.Validation.Enabled,
|
||||
Disabled: config.Validation.Disabled,
|
||||
Manifests: config.Validation.Manifests,
|
||||
}
|
||||
|
||||
return configCopy
|
||||
}
|
||||
|
Reference in New Issue
Block a user