Skip to content

Commit

Permalink
Update CNAB airgap example
Browse files Browse the repository at this point in the history
This updates the airgap example to demonstrate how to include referenced
images in the bundle when it is archived to a tgz, and how to update
your manifests to use the new image location after the images are
published on the other side of the airgap.

With helm's set command this is a bit easier to accomplish, here is an
example bundle that uses helm:

https://github.com/getporter/porter/tree/main/examples/airgap

I am using yq to help modify the manifest. I think kustomize can do it
as well.

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
  • Loading branch information
carolynvs committed Oct 23, 2020
1 parent 392c9f6 commit 9f1e469
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 84 deletions.
1 change: 1 addition & 0 deletions delivery/CNABwithPorter/.dockerignore
Expand Up @@ -2,3 +2,4 @@
# Put files here that you don't want copied into your bundle's invocation image
.gitignore
Dockerfile.tmpl
*.tgz
1 change: 1 addition & 0 deletions delivery/CNABwithPorter/.gitignore
@@ -1,2 +1,3 @@
Dockerfile
.cnab/
*.tgz
7 changes: 5 additions & 2 deletions delivery/CNABwithPorter/Dockerfile.tmpl
Expand Up @@ -2,7 +2,11 @@ FROM debian:stretch

ARG BUNDLE_DIR

RUN apt-get update && apt-get install -y ca-certificates
RUN apt-get update && apt-get install -y ca-certificates curl

# Install yq
RUN curl -sLo /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/3.4.1/yq_linux_amd64 && \
chmod +x /usr/local/bin/yq

# This is a template Dockerfile for the bundle's invocation image
# You can customize it to use different base images, install tools and copy configuration files.
Expand All @@ -19,4 +23,3 @@ RUN apt-get update && apt-get install -y ca-certificates

# Use the BUNDLE_DIR build argument to copy files into the bundle
COPY . $BUNDLE_DIR
COPY ./manifests /cnab/app/manifests/hello-server
179 changes: 139 additions & 40 deletions delivery/CNABwithPorter/README.md
@@ -1,51 +1,150 @@
# My First Bundle

This is an empty bundle that porter has created to get you started!

# Contents

## porter.yaml

This is the porter manifest. See https://porter.sh/author-bundles/ for
details on every field and how to configure your bundle. This is a required
file.

## helpers.sh
# CNAB over an airgap

1. Make any changes necessary to your bundle's source files and build it.

```
porter build
```

1. Publish the bundle to a registry. You can change where the bundle is published with the `--tag` flag.

```
porter publish --tag mydockeruser/helloservice-porter:v0.1.0
```

1. Archive the bundle to create a tgz file containing the bundle _and_ any images referenced by
the bundle from the `images` section of the porter.yaml.

```
porter archive helloservice.tgz --tag mydockeruser/helloservice-porter:v0.1.0
```

1. Move the tgz file across the airgap, using removable media such as a USB stick or CD.

1. Publish the bundle to a registry on the other side of the airgap.

```
porter publish --archive helloservice.tgz --tag theotherside/helloservice-porter:v0.1.0
```

Porter will publish the bundle, and any referenced images contained in the
archive, to the destination registry. The installer image and referenced
images are pushed to a single repository and do not preserve their tags.
This ensures that when someone installs a bundle, if they have access to the
bundle repository, they are guaranteed to have access to the installer image
and the referenced images.

Learn more about what to [expect the images to look like in the destination
repository](https://porter.sh/distribute-bundles/#image-references-after-publishing).
There is an [open issue](https://github.com/cnabio/cnab-to-oci/issues/104)
to preserve the tags.

1. Generate a credential set that says where to find the any credentials
required by the bundle. In this case, the bundle requires a kubeconfig for a
cluster on the other side of the airgap. This cluster should have access to
the airgapped registry where the bundle was published.

```console
$ porter credentials generate kube --tag theotherside/helloservice-porter:v0.1.0
Generating new credential kube from bundle hello-server
==> 1 credentials required for bundle hello-server
? How would you like to set credential "kubeconfig"
file path
? Enter the path that will be used to set credential "kubeconfig"
$HOME/.kube/config

$ porter credentials list
NAME MODIFIED
kube 3 hours ago
```

1. Install the bundle using the new reference that is accessible on this side of the airgap.

```
porter install helloservice-demo --tag theotherside/helloservice-porter:v0.1.0 -c kube
```

You can inspect the deployment to see that the image used by the deployment is
the one published to the airgapped registry. In the example below the archived
bundle was published to a local docker registry, localhost:5000, to simulate
moving it across an airgap.

```console
$ kubectl describe deployment -n demospace helloservice
Name: helloservice
Namespace: demospace
CreationTimestamp: Fri, 23 Oct 2020 14:00:27 -0500
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=helloservice
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=helloservice
Containers:
server:
Image: localhost:5000/helloservice-porter@sha256:3fe55b2bc6c9a31a2acdd7ee5c64cb076a267c11443d9bb12c1467272bf9af07
Port: 9000/TCP
Host Port: 0/TCP
Environment:
PORT: 9000
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: helloservice-76c9c95775 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 34s deployment-controller Scaled up replica set helloservice-76c9c95775 to 1
```

This is a bash script where you can place helper functions that you can call
from your porter.yaml file.
## Managing the bundle

## README.md
If you are testing this locally on the same machine, without a real airgap, make
sure to change directories so that you are not in the bundle's source directory
(where the porter.yaml is located). This ensures that the following commands are
executing against the published bundle and are not using the local bundle
source. When the `--tag` flag isn't specified, porter defaults to using the bundle
definition from the porter.yaml in the same directory.

This explains the files created by `porter create`. It is not used by porter and
can be deleted.
### View installed bundles

## Dockerfile.tmpl
```console
$ porter list
NAME CREATED MODIFIED LAST ACTION LAST STATUS
helloservice-demo 4 minutes ago 4 minutes ago install succeeded
```

This is a template Dockerfile for the bundle's invocation image. You can
customize it to use different base images, install tools and copy configuration
files. Porter will use it as a template and append lines to it for the mixin and to set
the CMD appropriately for the CNAB specification. You can delete this file if you don't
need it.
### Show installation details

Add the following line to **porter.yaml** to enable the Dockerfile template:
```console
porter show helloservice-demo
Name: helloservice-demo
Created: 33 minutes ago
Modified: 2 minutes ago

```yaml
dockerfile: Dockerfile.tmpl
History:
--------------------------------------
Action Timestamp Status
--------------------------------------
install 33 minutes ago succeeded
upgrade 2 minutes ago succeeded
```

By default, the Dockerfile template is disabled and Porter automatically copies
all of the files in the current directory into the bundle's invocation image. When
you use a custom Dockerfile template, you must manually copy files into the bundle
using COPY statements in the Dockerfile template.

## .gitignore
### Uninstall the bundle

This is a default file that we provide to help remind you which files are
generated by Porter, and shouldn't be committed to source control. You can
delete it if you don't need it.

## .dockerignore
```console
$ porter uninstall helloservice-demo -c kube
```

This is a default file that controls which files are copied into the bundle's
invocation image by default. You can delete it if you don't need it.
**NOTE**: We are in the middle of improving publish flags so that it's easier to
work with in parts, such as just changing the destination repo and not having to
specify the bundle version again. Expect the --tag flag to be marked for
deprecation next month (Nov 2020).
13 changes: 3 additions & 10 deletions delivery/CNABwithPorter/helpers.sh
@@ -1,16 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail

install() {
echo Hello World
}

upgrade() {
echo World 2.0
}

uninstall() {
echo Goodbye World
relocate() {
NEWIMAGE=$1
yq write -d 1 -i manifests/manifest.yaml 'spec.template.spec.containers.(name==server).image' $NEWIMAGE
}

# Call the requested function and pass the arguments as-is
Expand Down
6 changes: 5 additions & 1 deletion delivery/CNABwithPorter/manifests/manifest.yaml
@@ -1,3 +1,8 @@
apiVersion: v1
kind: Namespace
metadata:
name: demospace
---
apiVersion: apps/v1
kind: Deployment
metadata:
Expand All @@ -22,7 +27,6 @@ spec:
env:
- name: PORT
value: "9000"

---
apiVersion: v1
kind: Service
Expand Down
51 changes: 43 additions & 8 deletions delivery/CNABwithPorter/porter.yaml
Expand Up @@ -6,9 +6,8 @@
name: hello-server
version: 0.1.0
description: "A porter file for the hello server"
tag: aloisreitbauer/helloservice-porter:latest
tag: aloisreitbauer/helloservice-porter

# If you want to customize the Dockerfile in use, uncomment the line below and update the referenced file.
# See https://porter.sh/custom-dockerfile/
dockerfile: Dockerfile.tmpl

Expand All @@ -24,21 +23,57 @@ mixins:
- kubernetes:
clientVersion: v1.15.5

# Thick bundle configuration: Referenced images are stored in the bundle
# and moved with the bundle when archived and published to another location.
# When the bundle is published to a new location on the other side of an airgap
# Porter keeps these variables up-to-date so you can use them with helm, kustomize or yq
# to update your manifest or commands to use the relocated images
# See https://porter.sh/author-bundles/#images
images:
server: # v0.1.2
description: "The hello web server"
imageType: "docker"
repository: "aloisreitbauer/hello-server"
digest: "sha256:3fe55b2bc6c9a31a2acdd7ee5c64cb076a267c11443d9bb12c1467272bf9af07"

install:
# I'm using yq to update the image used by the manifest. If you were using helm,
# I wouldn't need this explicit step and could use `helm install ... --set` instead.
# example: https://github.com/getporter/porter/blob/5164b602e9528a0259c3a93f6eea4f1cf225f897/examples/airgap/porter.yaml#L31-L39
- exec:
description: "Update hello-server image with the relocated reference"
command: ./helpers.sh
arguments:
- relocate
- "{{bundle.images.server.repository}}@{{bundle.images.server.digest}}"
- kubernetes:
description: "Install the hello server"
manifests:
- /cnab/app/manifests/hello-server
- ./manifests
wait: true

upgrade:

- exec:
description: "Update hello-server image with the relocated reference"
command: ./helpers.sh
arguments:
- relocate
- "{{bundle.images.server.repository}}@{{bundle.images.server.digest}}"
- kubernetes:
description: "Install the hello server"
manifests:
- ./manifests
wait: true

uninstall:
- exec:
description: "Update hello-server image with the relocated reference"
command: ./helpers.sh
arguments:
- relocate
- "{{bundle.images.server.repository}}@{{bundle.images.server.digest}}"
- kubernetes:
description: "Uninstall the hello server"
manifests:
- /cnab/app/manifests/hello-server
wait: true


- ./manifests
wait: true

0 comments on commit 9f1e469

Please sign in to comment.