OpenTelemetry has various Go packages split across several Go modules that
often need to be carefully upgraded together. And in particular, we are
using the "semconv" package in conjunction with the OpenTelemetry SDK's
"resource" package in a way that requires that they both agree on which
version of the OpenTelemetry Semantic Conventions are being followed.
To help avoid "dependency hell" situations when upgrading, this centralizes
all of our direct calls into the OpenTelemetry SDK and tracing API into
packages under internal/tracing, by exposing a few thin wrapper functions
that other packages can use to access the same functionality indirectly.
We only use a relatively small subset of the OpenTelemetry library surface
area, so we don't need too many of these reexports and they should not
represent a significant additional maintenance burden.
For the semconv and resource interaction in particular this also factors
that out into a separate helper function with a unit test, so we should
notice quickly whenever they become misaligned. This complements the
end-to-end test previously added in opentofu/opentofu#3447 to give us
faster feedback about this particular problem, while the end-to-end test
has the broader scope of making sure there aren't any errors at all when
initializing OpenTelemetry tracing.
Finally, this also replaces the constants we previously had in package
traceaddrs with functions that return attribute.KeyValue values directly.
This matches the API style used by the OpenTelemetry semconv packages, and
makes the calls to these helpers from elsewhere in the system a little
more concise.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This adds more detailed OTel trace spans to our various different
interactions with OCI repositories, which is helpful to understand the
time spent in each of the various sequential steps involved in resolving
an OCI artifact.
OTel's centrally-maintained conventions for attribute names currently only
have a standard for reporting a manifest digest, so we'll use that where
it's appropriate but use our own "opentofu.oci."-prefixed attribute names
for everything else for now. Hopefully the upstream standard will be
broadened later to include some additional concepts, at which point we
can switch over to the standardized attribute names.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
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 is essentially a variation on PackageHTTPArchive that uses the
OCI Distribution protocol to retrieve a package from an OCI repository,
rather than directly from an HTTP URL.
It uses a similar technique of first downloading the package to a temporary
file and then delegating to the PackageLocalArchive location for the
final extraction, but it additionally verifies that the given OCI blob
descriptor seems reasonable and that the response matches the constraints
given in that descriptor.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>