Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

transport cmd #64

Open
wants to merge 105 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
8d25c2e
implements first version of new transport command
jschicktanz Sep 8, 2021
3f75dc1
reduces unix domain socket filepath length
jschicktanz Sep 8, 2021
b829dc0
working on down/upload of localOciBlob resources
jschicktanz Sep 9, 2021
f9269d0
refactoring
jschicktanz Sep 10, 2021
cd1102b
refactored
jschicktanz Sep 14, 2021
2d6b4f1
refactoring
jschicktanz Sep 14, 2021
58a6494
init
jschicktanz Sep 14, 2021
2813a7d
refactoring
jschicktanz Sep 14, 2021
a5bdb52
review feedback
jschicktanz Sep 16, 2021
4475238
run formatter
jschicktanz Sep 16, 2021
9d7a1d3
renames extension pkg and adds tests
jschicktanz Sep 20, 2021
38fd5ff
adds license headers
jschicktanz Sep 20, 2021
8fe0835
refactoring + adds test
jschicktanz Sep 20, 2021
5fbf6ba
fix tests and adds check for test processor binary
jschicktanz Sep 21, 2021
94da006
formatting
jschicktanz Sep 21, 2021
2c8504e
improves before suite check
jschicktanz Sep 21, 2021
a878e86
refactoring + adds processor timeouts
jschicktanz Sep 21, 2021
acc06be
refactoring + updates doc
jschicktanz Sep 21, 2021
e41fd55
refactoring, adds pipeline tests, adds labelling processor
jschicktanz Sep 22, 2021
d343d8c
wip
jschicktanz Sep 22, 2021
2103309
Merge branch 'transport-cmd-0' into transport-cmd
jschicktanz Sep 22, 2021
93933fa
restores deleted files and fixes compile errors
jschicktanz Sep 22, 2021
a5a016e
wip
jschicktanz Sep 27, 2021
dd28da3
wip
jschicktanz Oct 5, 2021
8acaba7
add config parser and pipeline compiler
enrico-kaack-comp Oct 6, 2021
b8908cb
wip
jschicktanz Oct 8, 2021
fa93196
Merge branch 'main' into transport-cmd
jschicktanz Oct 8, 2021
b59ae47
wip
jschicktanz Oct 12, 2021
3f84f86
wip
jschicktanz Oct 12, 2021
45818cc
should fix oci image filter
jschicktanz Oct 13, 2021
e62058b
refactoring and godoc
jschicktanz Oct 13, 2021
8b18f1e
refactors and improves config parsing
jschicktanz Oct 14, 2021
3c2a1ef
implements object factories
jschicktanz Oct 15, 2021
555ca81
implements processor factory
jschicktanz Oct 15, 2021
f21513a
fix compile errors + refactoring
jschicktanz Oct 18, 2021
7845707
adds upload of patched component descriptors
jschicktanz Oct 18, 2021
5d1142b
implement additional filters
jschicktanz Oct 19, 2021
5c3a5c2
makes transport cmd run through
jschicktanz Oct 19, 2021
21ce176
fixes filtering of gzip compressed layers
jschicktanz Oct 20, 2021
48955f9
increase processor timeout
jschicktanz Oct 20, 2021
4ca458d
refactoring
jschicktanz Oct 20, 2021
e183dc3
refactoring
jschicktanz Oct 20, 2021
75f5ba5
refactors filter package and adds tests
jschicktanz Oct 21, 2021
f6611fb
renames accessTypeFilter
jschicktanz Oct 21, 2021
6e247b6
format and lint
jschicktanz Oct 21, 2021
d2538a8
refactors filters package
jschicktanz Oct 21, 2021
c7c2cc3
adds filters package
jschicktanz Oct 21, 2021
6dbba63
Merge branch 'filters-package' into transport-cmd
jschicktanz Oct 21, 2021
02d0bb2
refactoring + added tests
jschicktanz Oct 26, 2021
54b89b9
adds tests for local oci blob downloader
jschicktanz Oct 26, 2021
6304559
refactoring + adds test for oci artifact downloader
jschicktanz Oct 26, 2021
4953cc3
refactoring + adds tests
jschicktanz Oct 28, 2021
00cb568
wip
jschicktanz Oct 28, 2021
06815ff
adds first test for oci image serialization
jschicktanz Oct 29, 2021
162707f
improves tests of oci artifact serialization
jschicktanz Nov 2, 2021
db92cd5
improves uploaders package
jschicktanz Nov 2, 2021
3b4a5dc
renames file
jschicktanz Nov 2, 2021
5b1ab2b
moves function to utils package and adds tests
jschicktanz Nov 2, 2021
e5fc684
renames labeling processor and adds test
jschicktanz Nov 3, 2021
e1d99f4
refactoring
jschicktanz Nov 3, 2021
779cd8c
refactoring
jschicktanz Nov 3, 2021
526e68f
use map[string]string for passing env variables
jschicktanz Nov 3, 2021
9fbcdc7
refactoring + changes doc
jschicktanz Nov 3, 2021
fc6e1a0
Merge branch 'transport-cmd-0' into transport-cmd
jschicktanz Nov 3, 2021
5325cbc
moves oci artifact serialization to process/utils package
jschicktanz Nov 3, 2021
2b2710c
updates license headers
jschicktanz Nov 3, 2021
fd1bf55
Merge branch 'main' into transport-cmd
jschicktanz Nov 3, 2021
5385d57
adds tests for utils
jschicktanz Nov 4, 2021
7c694d1
adds tests for filtering
jschicktanz Nov 9, 2021
9630a31
wip
jschicktanz Nov 10, 2021
2b9b508
adds test for image index in oci image filter
jschicktanz Nov 11, 2021
bc7da1d
comment out unnecessary code
jschicktanz Nov 11, 2021
a6e85fb
adds tests for config package
jschicktanz Nov 11, 2021
a2a335a
refactoring and docs added
jschicktanz Nov 12, 2021
648abf7
wip
jschicktanz Nov 19, 2021
e5b943b
wip
jschicktanz Nov 22, 2021
7f0e10c
adds testcase for oci artifact uploader
jschicktanz Nov 22, 2021
7ea523d
refactors oci uploader tests
jschicktanz Nov 24, 2021
9b24bd4
refactors test coding
jschicktanz Nov 24, 2021
2690218
refactors test coding
jschicktanz Nov 24, 2021
a296000
renames uds to unix domain socket
jschicktanz Nov 29, 2021
9dc8e97
review feedback
jschicktanz Nov 29, 2021
6d0d6d2
remove unix domain socket file after processor finished
jschicktanz Nov 29, 2021
128e337
Merge branch 'transport-cmd-0' into transport-cmd
jschicktanz Nov 30, 2021
38acc5b
fix compile error
jschicktanz Nov 30, 2021
4f49aa6
increase processor timeout
jschicktanz Nov 30, 2021
6dea353
wip
jschicktanz Dec 1, 2021
bea11b5
Merge branch 'main' into transport-cmd
jschicktanz Dec 2, 2021
d675ef2
adds component descriptor signature generation
jschicktanz Dec 13, 2021
ade22ae
improves logging and error handling
jschicktanz Dec 13, 2021
038e794
implements dry-run + refactoring
jschicktanz Dec 14, 2021
aa6e24f
refactoring
jschicktanz Dec 14, 2021
61edcc3
adds processor timeout cli option
jschicktanz Dec 14, 2021
0baa125
moves processing job to proces package
jschicktanz Dec 14, 2021
30e4a65
refactoring
jschicktanz Dec 15, 2021
f1074d6
Merge branch 'main' into transport-cmd
jschicktanz Dec 16, 2021
f848587
Merge branch 'main' into transport-cmd
jschicktanz Dec 21, 2021
1d9dce8
adds newline to output
jschicktanz Dec 21, 2021
afb2371
adds test for repo ctx override
jschicktanz Dec 21, 2021
92ca076
Merge branch 'main' into transport-cmd
jschicktanz Dec 21, 2021
a0dc11a
adds doc
jschicktanz Jan 10, 2022
f996602
Merge branch 'main' into transport-cmd
jschicktanz Jan 24, 2022
302d47c
removes signature coding
jschicktanz Jan 24, 2022
fb08e8b
remove unix domain socket file after processor exit
jschicktanz Jan 24, 2022
fb6cf9d
moves transport cmd to remote command
jschicktanz Jan 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,182 @@ In addition, an OCI Image is provided `docker run eu.gcr.io/gardener-project/com

Commands of the cli are hierarchically defined in [pkg/commands](./pkg/commands).
When a new command should be added make sure to commply to the google docs guidline for cli command (https://developers.google.com/style/code-syntax#required-items).

### Transport
The `transport` subcommand copies [Open Component Model (OCM)](https://github.com/gardener/component-spec) based applications between OCI registries or CTF artifacts. The command supports copy-by-reference and copy-by-value. Copy-by-reference only copies the component descriptors. Copy-by-value additionally copies all resources to new locations.

The basic flow of the `transport` subcommand is the following
```
- load component descriptor and all component references
- for componentDescriptor : componentDescriptors
- if copy-by-value
- for every resource : componentDescriptor.Resources
- download resource content from source location
- upload resource content to target location
- set resource.Access to target location
- upload patched component descriptor
```

If copy-by-value is enable, it is possible to modify resources during the resource copy process, see [here](#modifying-resources).

#### Configuration
The configuration for downloading and uploading the resources is handed over via the cli option `--transport-cfg-path`. The variable must point to a valid config file. The following snippet shows a basic config file for downloading and uploading resources of types `localOciBlob` and `ociImage`. It defines 1 downloader and 1 uploader for each resource type and matches these definitions to the actual resources via the `filters` attribute.

```yaml
meta:
version: v1

downloaders:
- name: 'oci-artifact-downloader'
type: 'OciArtifactDownloader'
filters:
- type: 'ResourceTypeFilter'
spec:
includeResourceTypes:
- 'ociImage'
- name: 'local-oci-blob-downloader'
type: 'LocalOciBlobDownloader'
filters:
- type: 'AccessTypeFilter'
spec:
includeAccessTypes:
- 'localOciBlob'

uploaders:
- name: 'oci-artifact-uploader'
type: 'OciArtifactUploader'
spec:
baseUrl: 'eu.gcr.io/target/images'
keepSourceRepo: false
filters:
- type: 'ResourceTypeFilter'
spec:
includeResourceTypes:
- 'ociImage'
- name: 'local-oci-blob-uploader'
type: 'LocalOciBlobUploader'
filters:
- type: 'AccessTypeFilter'
spec:
includeAccessTypes:
- 'localOciBlob'
```

Every resource that gets processed is matched against the filter definitions of each downloader and uploader. In order to work correctly, every resource must match against exactly 1 downloader and 1..n uploaders from the config file. There are builtin downloaders and uploaders, and also the possibility to extend the framework via external downloaders and uploaders, see [here](#extensions).

##### Modifying resources
Additionally to only downloading and reuploading resources, resources can be modified during the process. The units that perform the modifications are called *processors* and are defined in the config file. As with downloaders and uploaders, there are builtin processors, and also the possibility to extend the framework via external processors, see [here](#extensions).

The following snippet shows a config file for removing files from OCI artifact layers. It defines 2 processors of type `OciImageFilter` which should remove the *bin* and *etc* directories from all layers of an OCI artifact. These processors are matched against actual resources via `processingRules`. Every resource that gets processed is matched against the filter definitions of each processing rule. If all filters of a rule match, then the resource will get processed by the processors defined in the rule. It is possible that a resource matches 0..n processing rules.

```yaml
meta:
version: v1

downloaders:
...

uploaders:
...

processors:
- name: 'remove-bin-dir'
type: 'OciImageFilter'
spec:
removePatterns:
- 'bin/*'
- name: 'remove-etc-dir'
type: 'OciImageFilter'
spec:
removePatterns:
- 'etc/*'

processingRules:
- name: 'remove-bin-dir-from-test-component-images'
processors:
- name: 'remove-bin-dir'
type: 'processor'
filters:
- type: 'ComponentNameFilter'
spec:
includeComponentNames:
- 'github.com/test/test-component'
- type: 'ResourceTypeFilter'
spec:
includeResourceTypes:
- 'ociImage'
- name: 'remove-etc-dir-from-all-images'
processors:
- name: 'remove-etc-dir'
type: 'processor'
filters:
- type: 'ResourceTypeFilter'
spec:
includeResourceTypes:
- 'ociImage'
```

##### Repository Context Override
It is possible to load component descriptors from different OCI registries via the cli option `--repo-context-override-cfg`. It must point to a config file where the source repository contexts of component descriptors can be explicitely mapped. When downloading the source component descriptors, the program will first look into the repository context override file and try to match a component descriptor against each override definition. If no override matches, the default repository context from the cli option `--from` will be used. The following snippet shows a configuration, where the component `github.com/test/test-component` will be loaded from the repository context with base URL `eu.gcr.io/override`.

```yaml
meta:
version: v1
overrides:
- repositoryContext:
baseUrl: 'eu.gcr.io/override'
componentNameMapping: urlPath
type: ociRegistry
componentNameFilterSpec:
includeComponentNames:
- 'github.com/test/test-component'
```

#### Extensions
A pipeline for processing a single resource must consist of 1 downloader, 0..n processors, and 1..n uploaders. For each resource that gets processed, a unique chain of downloader, processors, and uploaders is created and is created based on the definitions in the config file. The elements in a chain are then called sequentially.

![resource processing](images/transport.png)

The downloader is the first element in a chain. It receives a TAR archive which contains 2 files. The first file is `component-descriptor.yaml` which contains the component descriptor in YAML format. The second file is `resource.yaml` which contains the YAML of the resource for which the chain is called. The downloader must then download the actual resource content based on this information. Once the content is downloaded, the downloader builds a new TAR archive for passing the information to subsequent processors. This TAR archive contains the `component-descriptor.yaml` and `resource.yaml`, and additionally the serialized resource content as a single blob file.

The subsequent processors can open the TAR archive, deserialize the resource content, perform the modifications to either the `resource.yaml` or the actual resource content, and again serialize the content for subsequent processors. Beware that the serialization format of all processors in a chain must match.

At the end of a processing pipeline are 1..n uploaders. They publish the resource content to a sink (OCI registry, CTF archive, S3 bucket, ...). As with the preceding steps, uploaders must also build a new TAR archive and pass the information to subsequent uploaders. Beware that uploaders must update the `access` attribute in the `resource.yaml` to point to the new resource location.

After all uploaders run through, the orchestrating program collects the modified `resource.yaml` files from the TAR archive and replaces the original resources in the component descriptor. The original component descriptor now contains the updated resources. As a final step, the modified component descriptor is uploaded.

Every stage of resource processing (downloaders, processors, uploaders) is extensible. An extension is a static binary, which reads a TAR archive as input (either via stdin or Unix Domain Sockets), performs its modifications, and then outputs a TAR archive with the modified content via stdout or Unix Domain Sockets. To describe extensions in the config file, use `type: 'Executable'` in the downloader/processor/uploader definition. The following snippet shows the definition of an extension processor.

```yaml
processors:
- name: 'test-extension'
type: 'Executable'
spec:
bin: '/path/to/binary'
args:
- '--test-arg'
- '42'
env:
TEST_ENV: '42'
```

When creating extensions, some details must be considered.

##### General points:
- One can chose whether the extension binary should support communication via stdin/stdout, Unix Domain Sockets, or both.

- Modifications of the component-descriptor.yaml file in a TAR archive are ignored when reuploading component descriptors and should therefore not be performed.

- The extension must read the input stream in a non-blocking fashion (e.g. directly write to temp file). If the stream is directly consumed as a TAR file, the writing side might block for large resources, as the TAR archive must first be completely written before it can be opened on the reading side.

- Beware that the serialization formats of the resource content must match between the downloader, processors, and uploaders of a resource processing chain. The serialization format is therefore an unseen part of the processor interface.

##### Points when usind Unix Domain Sockets:
- For Unix Domain Sockets, the calling program will set an environment variable which indicates the URL under which the Unix Domain Socket server of the extension binary should start. The calling program will try to connect to the extension via this URL.

- The extension program must stop the Unix Domain Socket server and stop, once it receives SIGTERM from the calling program.

- The extension program should remove the socket file in the file system once the program finishes.

##### Points when using stdin/stdout
- When using stdin/stdout for reading and writing processor TAR archives, beware that no other output like log data is allowed to be written to stdout. This data would otherwise interfere with the program data.
1 change: 1 addition & 0 deletions docs/reference/component-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ component cli
* [component-cli ctf](component-cli_ctf.md) -
* [component-cli image-vector](component-cli_image-vector.md) - command to add resource from a image vector and retrieve from a component descriptor
* [component-cli oci](component-cli_oci.md) -
* [component-cli transport](component-cli_transport.md) -
* [component-cli version](component-cli_version.md) - displays the version

39 changes: 39 additions & 0 deletions docs/reference/component-cli_transport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## component-cli transport



```
component-cli transport [flags]
```

### Options

```
--allow-plain-http allows the fallback to http if the oci registry does not support https
--cc-config string path to the local concourse config file
--dry-run only download component descriptors and perform matching of resources against transport config file. no component descriptors are uploaded, no resources are down/uploaded
--from string source repository base url
-h, --help help for transport
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--processor-timeout duration execution timeout for each individual processor (default 30s)
--registry-config string path to the dockerconfig.json with the oci registry authentication information
--repo-ctx-override-cfg string path to the repository context override config file
--to string target repository where the components are copied to
--transport-cfg string path to the transport config file
```

### Options inherited from parent commands

```
--cli logger runs as cli logger. enables cli logging
--dev enable development logging which result in console encoding, enabled stacktrace and enabled caller
--disable-caller disable the caller of logs (default true)
--disable-stacktrace disable the stacktrace of error logs (default true)
--disable-timestamp disable timestamp output (default true)
-v, --verbosity int number for the log level verbosity (default 1)
```

### SEE ALSO

* [component-cli](component-cli.md) - component cli

2 changes: 1 addition & 1 deletion hack/generate-docs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func main() {
cmd := app.NewComponentsCliCommand(context.TODO())
cmd.DisableAutoGenTag = true
check(doc.GenMarkdownTree(cmd, outputDir))
fmt.Printf("Successfully written docs to %s", outputDir)
fmt.Printf("Successfully written docs to %s\n", outputDir)
}

func printHelp() {
Expand Down
Binary file added images/transport.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions ociclient/mock/client_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 2 additions & 30 deletions pkg/commands/componentarchive/remote/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"errors"
"fmt"
"io"
"net/url"
"os"
"path"
"strings"
Expand All @@ -25,8 +24,6 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/gardener/component-cli/ociclient/oci"

"github.com/gardener/component-cli/ociclient"
"github.com/gardener/component-cli/ociclient/cache"

Expand Down Expand Up @@ -293,7 +290,7 @@ func (c *Copier) Copy(ctx context.Context, name, version string) error {
}

// mangle the target artifact name to keep the original image ref somehow readable.
target, err := targetOCIArtifactRef(c.TargetArtifactRepository, ociRegistryAcc.ImageReference, c.KeepSourceRepository)
target, err := utils.TargetOCIArtifactRef(c.TargetArtifactRepository, ociRegistryAcc.ImageReference, c.KeepSourceRepository)
if err != nil {
return fmt.Errorf("unable to create target oci artifact reference for resource %s: %w", res.Name, err)
}
Expand Down Expand Up @@ -333,7 +330,7 @@ func (c *Copier) Copy(ctx context.Context, name, version string) error {
}

src := path.Join(c.SourceArtifactRepository, relOCIRegistryAcc.Reference)
target, err := targetOCIArtifactRef(c.TargetArtifactRepository, src, c.KeepSourceRepository)
target, err := utils.TargetOCIArtifactRef(c.TargetArtifactRepository, src, c.KeepSourceRepository)
if err != nil {
return fmt.Errorf("unable to create target oci artifact reference for resource %s: %w", res.Name, err)
}
Expand Down Expand Up @@ -403,28 +400,3 @@ func (c *Copier) Copy(ctx context.Context, name, version string) error {

return nil
}

func targetOCIArtifactRef(targetRepo, ref string, keepOrigHost bool) (string, error) {
if !strings.Contains(targetRepo, "://") {
// add dummy protocol to correctly parse the url
targetRepo = "http://" + targetRepo
}
t, err := url.Parse(targetRepo)
if err != nil {
return "", err
}
parsedRef, err := oci.ParseRef(ref)
if err != nil {
return "", err
}

if !keepOrigHost {
parsedRef.Host = t.Host
parsedRef.Repository = path.Join(t.Path, parsedRef.Repository)
return parsedRef.String(), nil
}
replacedRef := strings.NewReplacer(".", "_", ":", "_").Replace(parsedRef.Name())
parsedRef.Repository = path.Join(t.Path, replacedRef)
parsedRef.Host = t.Host
return parsedRef.String(), nil
}
1 change: 1 addition & 0 deletions pkg/commands/componentarchive/remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func NewRemoteCommand(ctx context.Context) *cobra.Command {
cmd.AddCommand(NewPushCommand(ctx))
cmd.AddCommand(NewGetCommand(ctx))
cmd.AddCommand(NewCopyCommand(ctx))
cmd.AddCommand(NewTransportCommand(ctx))

return cmd
}
Loading