getproviders: Don't require artifactType on OCI layers for providers

The initial design of this attempted to maximize our flexibility to make
backward-compatible changes to the manifest structure for providers in
future OpenTofu releases, by expecting the "layers" entry describing the
provider package to include a specific artifactType and ignoring any
layers with different artifactType values.

However, general-purpose tools for constructing image manifests don't tend
to allow setting the artifactType in a layer descriptor, so we'll drop
that requirement as a measure of pragmatism.

This implies that the only possible extension we could make for _layers
in particular_ in a future release is to support an additional archive
format that would presumably then be used in much the same way as our
current archive/zip usage: by extracting the archive into the target
directory. This ability to introduce new formats is the most likely future
evolution we identified while designing this, with all other evolutions
being more speculative/theoretical.

This does still retain various other extension points for future additions,
including but not limited to:
- Introducing an alternative artifactType for the image manifest _itself_,
  rather than for the layers within it, and then having the later version
  of OpenTofu prefer to choose a manifest with the newer artifactType while
  still supporting the old one as a fallback.
- Using the "config" property of the manifest to introduce arbitrary
  additional metadata that future versions might need, and using the
  config descriptor's own mediaType to recognize when those new additions
  are present.

Therefore this seems like a reasonable compromise to make it easier to
assemble OCI manifests for OpenTofu provider packages using general-purpose
tools like ORAS CLI, rather than requiring OpenTofu-specific tools.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This commit is contained in:
Martin Atkins
2025-03-26 10:38:31 -07:00
parent c8cbd95c1f
commit 230ce34ffc
4 changed files with 5 additions and 61 deletions

View File

@@ -19,17 +19,6 @@ import (
orasContent "oras.land/oras-go/v2/content"
)
// ociPackageArtifactType is the specific artifact type we're expecting for the
// blob representing a final distribution package that we'll fetch and extract, after
// we've dug through all of the manifests.
//
// We silently ignore blobs that don't have this artifact type both so that future
// OpenTofu versions can potentially introduce new blobs with different purposes and
// so that a manifest can have other blobs listed in it for purposes that are
// irrelevant to OpenTofu's interests, in case that becomes useful in the broader
// OCI ecosystem.
const ociPackageArtifactType = "application/vnd.opentofu.providerpkg"
// ociPackageMediaType is the specific media type we're expecting for the blob
// representing a final distribution package that we'll fetch and extract, after
// we've dug through all of the manifests.
@@ -273,16 +262,6 @@ func hashFromOCIDigest(digest ociDigest.Digest) (Hash, error) {
}
func checkOCIBlobDescriptor(desc ociv1.Descriptor, meta PackageMeta) error {
if desc.ArtifactType != ociPackageArtifactType {
if desc.ArtifactType == "application/vnd.opentofu.modulepkg" {
// Seems like someone has tried to use a module package where a
// provider package was expected. Confusion beween modules and
// providers is common for those new to OpenTofu, so we'll
// use a more specific diagnosis for this.
return fmt.Errorf("selected OCI artifact is a module package rather than a provider package")
}
return fmt.Errorf("selected OCI artifact has unexpected type %q", desc.ArtifactType)
}
if desc.MediaType != ociPackageMediaType {
return fmt.Errorf("selected OCI artifact manifest has unexpected media type %q", desc.MediaType)
}