Skip to content

Commit

Permalink
Reserve manifest version 1.0.2 for depsv2
Browse files Browse the repository at this point in the history
While not an offially released version of the manifest, I have reserved 1.0.2 for bundles that define advanced dependencies. The schemaVersion of a bundle can only be set to 1.0.2 when the v2 dependencies experimental feature is enabled.

The docs still point to 1.0.1 as the latest version, and by default bundles are created with 1.0.1 and validated against 1.0.1. Once we are sure that our schema changes are solid and won't be modified further under the experimental flag (ideally waiting until the flag is removed) then we can release 1.0.2 and default to it.

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
  • Loading branch information
carolynvs committed Feb 28, 2023
1 parent a906f8d commit 3ab43a9
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 57 deletions.
2 changes: 1 addition & 1 deletion pkg/cnab/config-adapter/testdata/myenv-depsv2.bundle.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"version": "v1.2.3"
}
},
"manifest": "c2NoZW1hVmVyc2lvbjogMS4wLjAKbmFtZTogbXllbnYKdmVyc2lvbjogMC4xLjAKZGVzY3JpcHRpb246ICJBICdtZXRhJyBidW5kbGUgdGhhdCBkZXBsb3lzIGV2ZXJ5dGhpbmcgaXQgbmVlZHMgYnkgYWRkaW5nIGRlcGVuZGVuY2llcyIKcmVnaXN0cnk6ICJsb2NhbGhvc3Q6NTAwMCIKCmNyZWRlbnRpYWxzOgogIC0gbmFtZTogdG9rZW4KCnBhcmFtZXRlcnM6CiAgLSBuYW1lOiBsb2dMZXZlbAogICAgdHlwZTogc3RyaW5nCiAgICBkZWZhdWx0OiBpbmZvCgpkZXBlbmRlbmNpZXM6CiAgcmVxdWlyZXM6CiAgICAtIG5hbWU6IGluZnJhCiAgICAgIGJ1bmRsZToKICAgICAgICByZWZlcmVuY2U6ICJsb2NhbGhvc3Q6NTAwMC9teWluZnJhOnYwLjEuMCIKICAgICAgICAjIFRPRE8oUEVQMDAzKTogSW1wbGVtZW50IHdpdGggaHR0cHM6Ly9naXRodWIuY29tL2dldHBvcnRlci9wb3J0ZXIvaXNzdWVzLzI1NDgKICAgICAgICAjaW50ZXJmYWNlOgogICAgICAgICMgIGRvY3VtZW50OgogICAgICAgICMgICAgb3V0cHV0czoKICAgICAgICAjICAgICAgLSBuYW1lOiBteXNxbC1jb25uc3RyCiAgICAgICAgIyAgICAgICAgJGlkOiAiZ2V0cG9ydGVyLm9yZy9pbnRlcmZhY2VzL215c3FsLmNvbm5lY3Rpb24tc3RyaW5nIgogICAgICBjcmVkZW50aWFsczoKICAgICAgICB0b2tlbjogJHtidW5kbGUuY3JlZGVudGlhbHMudG9rZW59CiAgICAgIHBhcmFtZXRlcnM6CiAgICAgICAgZGF0YWJhc2U6IG15ZW52ZGIKICAgICAgICBsb2dMZXZlbDogJHtidW5kbGUucGFyYW1ldGVycy5sb2dMZXZlbH0KICAgIC0gbmFtZTogYXBwCiAgICAgIGJ1bmRsZToKICAgICAgICByZWZlcmVuY2U6ICJsb2NhbGhvc3Q6NTAwMC9teWFwcDp2MS4yLjMiCiAgICAgIGNyZWRlbnRpYWxzOgogICAgICAgIGRiLWNvbm5zdHI6ICR7YnVuZGxlLmRlcGVuZGVuY2llcy5pbmZyYS5vdXRwdXRzLm15c3FsLWNvbm5zdHJ9CiAgICAgIHBhcmFtZXRlcnM6CiAgICAgICAgbG9nTGV2ZWw6ICR7YnVuZGxlLnBhcmFtZXRlcnMubG9nTGV2ZWwgfQoKIyBUaGUgcmVzdCBiZWxvdyBpcyBib2lsZXJwbGF0ZSB0byBtYWtlIHBvcnRlciBoYXBweQojIFNpbmNlIHRoaXMgaXMgYSAibWV0YSIgYnVuZGxlLCBpdCBkb2Vzbid0IGRvIGFueXRoaW5nIGl0c2VsZiwganVzdCByZWZlcmVuY2VzIG90aGVyIGJ1bmRsZXMKbWl4aW5zOgogIC0gZXhlYwoKaW5zdGFsbDoKICAtIGV4ZWM6CiAgICAgIGNvbW1hbmQ6IGVjaG8KICAgICAgYXJndW1lbnRzOgogICAgICAgIC0gIkluc3RhbGxpbmcgYW4gZW52aXJvbm1lbnQiCgp1cGdyYWRlOgogIC0gZXhlYzoKICAgICAgY29tbWFuZDogZWNobwogICAgICBhcmd1bWVudHM6CiAgICAgICAgLSAiVXBncmFkaW5nIGFuIGVudmlyb25tZW50IgoKdW5pbnN0YWxsOgogIC0gZXhlYzoKICAgICAgY29tbWFuZDogZWNobwogICAgICBhcmd1bWVudHM6CiAgICAgICAgLSAiVW5pbnN0YWxsaW5nIGFuIGVudmlyb25tZW50Igo=",
"manifest": "c2NoZW1hVmVyc2lvbjogMS4wLjIKbmFtZTogbXllbnYKdmVyc2lvbjogMC4xLjAKZGVzY3JpcHRpb246ICJBICdtZXRhJyBidW5kbGUgdGhhdCBkZXBsb3lzIGV2ZXJ5dGhpbmcgaXQgbmVlZHMgYnkgYWRkaW5nIGRlcGVuZGVuY2llcyIKcmVnaXN0cnk6ICJsb2NhbGhvc3Q6NTAwMCIKCmNyZWRlbnRpYWxzOgogIC0gbmFtZTogdG9rZW4KCnBhcmFtZXRlcnM6CiAgLSBuYW1lOiBsb2dMZXZlbAogICAgdHlwZTogc3RyaW5nCiAgICBkZWZhdWx0OiBpbmZvCgpkZXBlbmRlbmNpZXM6CiAgcmVxdWlyZXM6CiAgICAtIG5hbWU6IGluZnJhCiAgICAgIGJ1bmRsZToKICAgICAgICByZWZlcmVuY2U6ICJsb2NhbGhvc3Q6NTAwMC9teWluZnJhOnYwLjEuMCIKICAgICAgICAjIFRPRE8oUEVQMDAzKTogSW1wbGVtZW50IHdpdGggaHR0cHM6Ly9naXRodWIuY29tL2dldHBvcnRlci9wb3J0ZXIvaXNzdWVzLzI1NDgKICAgICAgICAjaW50ZXJmYWNlOgogICAgICAgICMgIGRvY3VtZW50OgogICAgICAgICMgICAgb3V0cHV0czoKICAgICAgICAjICAgICAgLSBuYW1lOiBteXNxbC1jb25uc3RyCiAgICAgICAgIyAgICAgICAgJGlkOiAiZ2V0cG9ydGVyLm9yZy9pbnRlcmZhY2VzL215c3FsLmNvbm5lY3Rpb24tc3RyaW5nIgogICAgICBjcmVkZW50aWFsczoKICAgICAgICB0b2tlbjogJHtidW5kbGUuY3JlZGVudGlhbHMudG9rZW59CiAgICAgIHBhcmFtZXRlcnM6CiAgICAgICAgZGF0YWJhc2U6IG15ZW52ZGIKICAgICAgICBsb2dMZXZlbDogJHtidW5kbGUucGFyYW1ldGVycy5sb2dMZXZlbH0KICAgIC0gbmFtZTogYXBwCiAgICAgIGJ1bmRsZToKICAgICAgICByZWZlcmVuY2U6ICJsb2NhbGhvc3Q6NTAwMC9teWFwcDp2MS4yLjMiCiAgICAgIGNyZWRlbnRpYWxzOgogICAgICAgIGRiLWNvbm5zdHI6ICR7YnVuZGxlLmRlcGVuZGVuY2llcy5pbmZyYS5vdXRwdXRzLm15c3FsLWNvbm5zdHJ9CiAgICAgIHBhcmFtZXRlcnM6CiAgICAgICAgbG9nTGV2ZWw6ICR7YnVuZGxlLnBhcmFtZXRlcnMubG9nTGV2ZWwgfQoKIyBUaGUgcmVzdCBiZWxvdyBpcyBib2lsZXJwbGF0ZSB0byBtYWtlIHBvcnRlciBoYXBweQojIFNpbmNlIHRoaXMgaXMgYSAibWV0YSIgYnVuZGxlLCBpdCBkb2Vzbid0IGRvIGFueXRoaW5nIGl0c2VsZiwganVzdCByZWZlcmVuY2VzIG90aGVyIGJ1bmRsZXMKbWl4aW5zOgogIC0gZXhlYwoKaW5zdGFsbDoKICAtIGV4ZWM6CiAgICAgIGNvbW1hbmQ6IGVjaG8KICAgICAgYXJndW1lbnRzOgogICAgICAgIC0gIkluc3RhbGxpbmcgYW4gZW52aXJvbm1lbnQiCgp1cGdyYWRlOgogIC0gZXhlYzoKICAgICAgY29tbWFuZDogZWNobwogICAgICBhcmd1bWVudHM6CiAgICAgICAgLSAiVXBncmFkaW5nIGFuIGVudmlyb25tZW50IgoKdW5pbnN0YWxsOgogIC0gZXhlYzoKICAgICAgY29tbWFuZDogZWNobwogICAgICBhcmd1bWVudHM6CiAgICAgICAgLSAiVW5pbnN0YWxsaW5nIGFuIGVudmlyb25tZW50Igo=",
"version": "",
"commit": ""
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/cnab/config-adapter/testdata/porter-with-depsv2.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
schemaVersion: 1.0.0
schemaVersion: 1.0.2
name: porter-hello
version: 0.1.0
description: "An example Porter configuration"
Expand Down
59 changes: 40 additions & 19 deletions pkg/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"get.porter.sh/porter/pkg/cnab"
"get.porter.sh/porter/pkg/config"
"get.porter.sh/porter/pkg/experimental"
"get.porter.sh/porter/pkg/portercontext"
"get.porter.sh/porter/pkg/schema"
"get.porter.sh/porter/pkg/tracing"
Expand All @@ -24,6 +25,7 @@ import (
"github.com/cnabio/cnab-go/bundle/definition"
"github.com/hashicorp/go-multierror"
"github.com/opencontainers/go-digest"
"go.opentelemetry.io/otel/attribute"
)

const (
Expand All @@ -39,6 +41,11 @@ const (
)

var (
// TODO(PEP003): Version 1.0.2 is behind the DependenciesV2 feature flag. We update the supported versions later
// when validating a bundle and only allow that version when it is enabled.
// The default version remains on the last stable version 1.0.1.
// When the schema version is stable and not behind a feature flag, we can update the supported versions and default version.

// SupportedSchemaVersions is the Porter manifest (porter.yaml) schema
// versions supported by this version of Porter, specified as a semver range.
// When the Manifest structure is changed, this field should be incremented.
Expand Down Expand Up @@ -109,21 +116,24 @@ type Manifest struct {
Required []RequiredExtension `yaml:"required,omitempty"`
}

func (m *Manifest) Validate(cxt *portercontext.Context, strategy schema.CheckStrategy) error {
func (m *Manifest) Validate(ctx context.Context, cfg *config.Config) error {
ctx, span := tracing.StartSpan(ctx)
defer span.EndSpan()

var result error

err := m.validateMetadata(cxt, strategy)
err := m.validateMetadata(ctx, cfg)
if err != nil {
return err
}

err = m.SetDefaults()
if err != nil {
return err
return span.Error(err)
}

if strings.ToLower(m.Dockerfile) == "dockerfile" {
return errors.New("Dockerfile template cannot be named 'Dockerfile' because that is the filename generated during porter build")
return span.Error(errors.New("Dockerfile template cannot be named 'Dockerfile' because that is the filename generated during porter build"))
}

if len(m.Mixins) == 0 {
Expand Down Expand Up @@ -154,7 +164,7 @@ func (m *Manifest) Validate(cxt *portercontext.Context, strategy schema.CheckStr
}

for _, dep := range m.Dependencies.Requires {
err = dep.Validate(cxt)
err = dep.Validate(cfg.Context)
if err != nil {
result = multierror.Append(result, err)
}
Expand All @@ -181,34 +191,46 @@ func (m *Manifest) Validate(cxt *portercontext.Context, strategy schema.CheckStr
}
}

return result
return span.Error(result)
}

func (m *Manifest) validateMetadata(cxt *portercontext.Context, strategy schema.CheckStrategy) error {
func (m *Manifest) validateMetadata(ctx context.Context, cfg *config.Config) error {
ctx, span := tracing.StartSpan(ctx)
defer span.EndSpan()

strategy := cfg.GetSchemaCheckStrategy(ctx)
span.SetAttributes(attribute.String("schemaCheckStrategy", string(strategy)))

if m.SchemaType == "" {
m.SchemaType = SchemaTypeBundle
} else if !strings.EqualFold(m.SchemaType, SchemaTypeBundle) {
return fmt.Errorf("invalid schemaType %s, expected %s", m.SchemaType, SchemaTypeBundle)
return span.Errorf("invalid schemaType %s, expected %s", m.SchemaType, SchemaTypeBundle)
}

if warnOnly, err := schema.ValidateSchemaVersion(strategy, SupportedSchemaVersions, m.SchemaVersion, DefaultSchemaVersion); err != nil {
// Check what the supported schema version is based on if depsv2 is enabled
supportedVersions := SupportedSchemaVersions
if cfg.IsFeatureEnabled(experimental.FlagDependenciesV2) {
supportedVersions, _ = semver.NewConstraint("1.0.0-alpha.1 || 1.0.0 - 1.0.2")
}

if warnOnly, err := schema.ValidateSchemaVersion(strategy, supportedVersions, m.SchemaVersion, DefaultSchemaVersion); err != nil {
if warnOnly {
fmt.Fprintln(cxt.Err, err)
span.Warn(err.Error())
} else {
return err
return span.Error(err)
}
}

if m.Name == "" {
return errors.New("bundle name must be set")
return span.Error(errors.New("bundle name must be set"))
}

if m.Registry == "" && m.Reference == "" {
return errors.New("a registry or reference value must be provided")
return span.Error(errors.New("a registry or reference value must be provided"))
}

if m.Reference != "" && m.Registry != "" {
fmt.Fprintf(cxt.Out, "WARNING: both registry and reference were provided; "+
span.Warnf("WARNING: both registry and reference were provided; "+
"using the reference value of %s for the bundle reference\n", m.Reference)
}

Expand All @@ -217,7 +239,7 @@ func (m *Manifest) validateMetadata(cxt *portercontext.Context, strategy schema.
if m.Version != "" {
v, err := semver.NewVersion(m.Version)
if err != nil {
return fmt.Errorf("version %q is not a valid semver value: %w", m.Version, err)
return span.Errorf("version %q is not a valid semver value: %w", m.Version, err)
}
m.Version = v.String()
}
Expand Down Expand Up @@ -716,12 +738,12 @@ type BundleCriteria struct {
// Either bundle or reference may be specified but not both.
type BundleInterface struct {
// Reference specifies an OCI reference to a bundle to use as the interface on top of how the bundle is used.
Reference string `yaml:"reference,omitempty"`
Reference string `yaml:"reference,omitempty"`

// Document specifies additional constraints that should be added to the bundle interface.
// By default, Porter only requires the name and the type to match, additional jsonschema values can be specified to restrict matching bundles even further.
// The value should be a jsonschema document containing relevant sub-documents from a bundle.json that should be applied to the base bundle interface.
Document *BundleInterfaceDocument `yaml:"document,omitempty"`
Document *BundleInterfaceDocument `yaml:"document,omitempty"`
}

// BundleInterfaceDocument specifies the interface that a bundle must support in
Expand Down Expand Up @@ -1232,8 +1254,7 @@ func LoadManifestFrom(ctx context.Context, config *config.Config, file string) (
return nil, err
}

strategy := config.GetSchemaCheckStrategy(ctx)
if err = m.Validate(config.Context, strategy); err != nil {
if err = m.Validate(ctx, config); err != nil {
return nil, err
}

Expand Down
Loading

0 comments on commit 3ab43a9

Please sign in to comment.