05-transporting-component-versions

command
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2024 License: Apache-2.0 Imports: 23 Imported by: 0

README

Transporting Component Versions

This tour illustrates the basic support for transporting content from one environment into another.

Running the example

You can call the main program with a config file option (--config <file>). The config file should have the following content:

repository: ghcr.io/mandelsoft/ocm
targetRepository:
  type: CommonTransportFormat
  filePath: /tmp/example05.target.ctf
  fileFormat: directory
  accessMode: 2
username:
password:

Any supported kind of target repository can be specified by using its specification type. An OCI regisztry target would look like this:

repository: ghcr.io/mandelsoft/ocm
username:
password:
targetRepository:
  type: OCIRegistry
  baseUrl: ghcr.io/mandelsoft/targetocm
ocmConfig: <config file>

The actual version of the example just works with the file system target, because it is not possible to specify credentials for the target repository in this simple config file. But, if you specify an OCM config file you can add more predefined credential settings to make it possible to use target repositories requiring credentials. The credentials are automatically taken from the credentials context and don't need to be specified when creating the repository access object in the code.

Walkthrough

As usual, we start with getting access to an OCM context

	ctx := ocm.DefaultContext()

Then we configure this context with optional ocm config defined in our config file. See OCM config scenario in tour 04.

	err := ReadConfiguration(ctx, cfg)
	if err != nil {
		return err
	}

This function simply applies the config file using the utility function provided by the config management:

func ReadConfiguration(ctx ocm.Context, cfg *helper.Config) error {
	if cfg.OCMConfig != "" {
		fmt.Printf("*** applying config from %s\n", cfg.OCMConfig)

		_, err := utils.Configure(ctx, cfg.OCMConfig)
		if err != nil {
			return errors.Wrapf(err, "error in ocm config %s", cfg.OCMConfig)
		}
	}
	return nil
}

The context acts as factory for various model types based on specification descriptor serialization formats in YAML or JSON. Access method specifications and repository specification are examples for this feature.

Now, we use the repository specification serialization format to determine the target repository for a transport from our yaml configuration file.

	fmt.Printf("target repository is %s\n", string(cfg.Target))
	target, err := ctx.RepositoryForConfig(cfg.Target, nil)
	if err != nil {
		return errors.Wrapf(err, "cannot open repository")
	}
	defer target.Close()

For our source we just use the component version provided by the last examples in a remote repository. Therefore, we set up the credentials context, as shown in tour 03.

	id, err := oci.GetConsumerIdForRef(cfg.Repository)
	if err != nil {
		return errors.Wrapf(err, "invalid consumer")
	}
	creds := ociidentity.SimpleCredentials(cfg.Username, cfg.Password)
	ctx.CredentialsContext().SetCredentialsForConsumer(id, creds)

For the transport, we first get access to the component version we want to transport, by getting the source repository and looking up the desired component version.

	spec := ocireg.NewRepositorySpec(cfg.Repository, nil)
	repo, err := ctx.RepositoryForSpec(spec, creds)
	if err != nil {
		return err
	}
	defer repo.Close()

	cv, err := repo.LookupComponentVersion("acme.org/example03", "v0.1.0")
	if err != nil {
		return errors.Wrapf(err, "added version not found")
	}
	defer cv.Close()

We could just add this version to the target repository, but this would not be a real transport, but just a copy of the component descriptor and the associated local resources. Transport potentially means more, all the described artifacts should also be copied into the target environment.

Such an action is done by the library function transfer.Transfer. It takes several settings influencing the transport mode, for example transitive or value transport. Here, all resources are transported per value, all external references will be inlined as localBlobs and imported into the target environment, applying blob upload handlers where possible. For a CTF archive as target, there are no configured handlers by default. Therefore, all resources will be migrated to local blobs.

	err = transfer.Transfer(cv, target, standard.ResourcesByValue(), standard.Overwrite())
	if err != nil {
		return errors.Wrapf(err, "transport failed")
	}

Now, we check the result of our transport action in the target repository.

	tcv, err := target.LookupComponentVersion("acme.org/example03", "v0.1.0")
	if err != nil {
		return errors.Wrapf(err, "transported version not found")
	}
	defer tcv.Close()
	fmt.Printf("*** target version in transportation target\n")
	err = describeVersion(tcv)
	if err != nil {
		return errors.Wrapf(err, "describe failed")
	}

Please be aware that all resources in the target now are localBlobs, if the target is a CTF archive. If it is an OCI registry, all the OCI artifact resources will be uploaded as OCI artifacts into the target repository and the access specifications are adapted to type ociArtifact, but now referring to OCI artifacts in the target repository.

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL