Regardless of the Out of the Box Supply Chain Package you’ve installed, you can provide source code for the workload either from a directory in your local computer’s file system or from a Git repository.
Supply Chain
-- fetch source * either from Git or local directory
-- test
-- build
-- scan
-- apply-conventions
-- push config
This document provides details about both approaches.
Note: To provide a prebuilt container image instead of building the application from the beginning by using the supply chain, see Using a prebuilt image.
To provide source code from a Git repository to the supply chains, you must fill workload.spec.source.git
. With the tanzu
CLI, you can do so by using the following flags:
--git-branch
: branch within the Git repository to checkout--git-commit
: commit SHA within the Git repository to checkout--git-repo
: Git URL to remote source code--git-tag
: tag within the Git repository to checkoutFor example, after installing ootb-supply-chain-basic
, to create a Workload
the source code for which comes from the main
branch of the github.com/sample-accelerators/tanzu-java-web-app
Git repository, run:
tanzu apps workload create tanzu-java-web-app \
--app tanzu-java-web-app \
--type web \
--git-repo https://github.com/sample-accelerators/tanzu-java-web-app \
--git-branch main
Expect to see the following output:
Create workload:
1 + |---
2 + |apiVersion: carto.run/v1alpha1
3 + |kind: Workload
4 + |metadata:
5 + | labels:
6 + | app.kubernetes.io/part-of: tanzu-java-web-app
7 + | apps.tanzu.vmware.com/workload-type: web
8 + | name: tanzu-java-web-app
9 + | namespace: default
10 + |spec:
11 + | source:
12 + | git:
13 + | ref:
14 + | branch: main
15 + | url: https://github.com/sample-accelerators/tanzu-java-web-app
ImportantThe Git repository URL must include the scheme:
http://
,https://
, orssh://
.
GitRepository
To fetch source code from a repository that requires credentials, you must provide those by using a Kubernetes secret object that is referenced by the GitRepostiory
object created for that workload. See How It Works to learn more about the underlying process of detecting changes to the repository.
Workload/tanzu-java-web-app
└─GitRepository/tanzu-java-web-app
└───────> secretRef: {name: GIT-SECRET-NAME}
|
either a default from TAP installation or
gitops_ssh_secret Workload parameter
Platform operators who install the Out of the Box Supply Chain packages by using Tanzu Application Platform profiles can customize the default name of the secret (git-ssh
) by editing the corresponding ootb_supply_chain*
property in the tap-values.yaml
file:
ootb_supply_chain_basic:
gitops:
ssh_secret: GIT-SECRET-NAME
For platform operators who install the ootb-supply-chain-*
package individually by using tanzu package install
, they can edit the ootb-supply-chain-*-values.yml
as follows:
gitops:
ssh_secret: GIT-SECRET-NAME
You can also override the default secret name directly in the workload by using the gitops_ssh_secret
parameter, regardless of how Tanzu Application Platform is installed. You can use the --param
flag in Tanzu CLI. For example:
tanzu apps workload create tanzu-java-web-app \
--app tanzu-java-web-app \
--type web \
--git-repo https://github.com/sample-accelerators/tanzu-java-web-app \
--git-branch main \
--param gitops_ssh_secret=SECRET-NAME
Expect to see the following output:
Create workload:
1 + |---
2 + |apiVersion: carto.run/v1alpha1
3 + |kind: Workload
4 + |metadata:
5 + | labels:
6 + | app.kubernetes.io/part-of: tanzu-java-web-app
7 + | apps.tanzu.vmware.com/workload-type: web
8 + | name: tanzu-java-web-app
9 + | namespace: default
10 + |spec:
11 + | params:
12 + | - name: gitops_ssh_secret #! parameter that overrides the default
13 + | value: GIT-SECRET-NAME #! secret name
14 + | source:
15 + | git:
16 + | ref:
17 + | branch: main
18 + | url: https://github.com/sample-accelerators/tanzu-java-web-app
Note: A secret reference is only provided to
GitRepository
ifgitops_ssh_secret
is set to a non-empty string in some fashion, either by a package property or a workload parameter. To force aGitRepository
to not reference a secret, set the value to an empty string (""
).
After defining the name of the Kubernetes secret, you can define the secret.
Despite both the package value and workload parameter being called gitops.ssh_secret
, you can use HTTP(S) transports as well:
Ensure that the repository in the Workload
specification uses http://
or https://
schemes in any URLs that relate to the repositories. For example, https://github.com/my-org/my-repo
instead of github.com/my-org/my-repo
or ssh://github.com:my-org/my-repo
.
In the same namespace as the workload, create a Kubernetes secret object of type kubernetes.io/basic-auth
with the name matching the one expected by the supply chain as explained in the earlier section. For example:
apiVersion: v1
kind: Secret
metadata:
name: GIT-SECRET-NAME
annotations:
tekton.dev/git-0: GIT-SERVER # ! required
type: kubernetes.io/basic-auth
stringData:
username: GIT-USERNAME
password: GIT-PASSWORD
With the secret created with the name matching the one configured for gitops.ssh_secret
, attach it to the ServiceAccount
used by the workload. For example:
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
secrets:
- name: registry-credentials
- name: tap-registry
- name: GIT-SECRET-NAME
imagePullSecrets:
- name: registry-credentials
- name: tap-registry
For more information about the credentials and setting up the Kubernetes secret, see Git Authentication’s HTTP section.
Aside from using HTTP(S) as a transport, you can also use SSH:
Ensure that the repository URL in the workload specification uses ssh://
as the scheme in the URL, for example, ssh://git@github.com:my-org/my-repo.git
.
Create a Kubernetes secret object of type kubernetes.io/ssh-auth
:
apiVersion: v1
kind: Secret
metadata:
name: GIT-SECRET-NAME
annotations:
tekton.dev/git-0: GIT-SERVER
type: kubernetes.io/ssh-auth
stringData:
ssh-privatekey: SSH-PRIVATE-KEY # private key with push-permissions
identity: SSH-PRIVATE-KEY # private key with pull permissions
identity.pub: SSH-PUBLIC-KEY # public of the `identity` private key
known_hosts: GIT-SERVER-PUBLIC-KEYS # git server public keys
With the secret created with the name matching the one configured for gitops.ssh_secret
, attach it to the ServiceAccount used by the workload. For example:
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
secrets:
- name: registry-credentials
- name: tap-registry
- name: GIT-SECRET-NAME
imagePullSecrets:
- name: registry-credentials
- name: tap-registry
To learn more about how to generate the keys and set it up with the Git server, see Git Authentication’s SSH section.
With the workload.spec.source.git
filled, the supply chain takes care of managing a child GitRepository
object that keeps track of commits made to the Git repository stated in workload.spec.source.git
.
For each revision found, gitrepository.status.artifact
gets updated providing information about an HTTP endpoint that the controller makes available for other components to fetch the source code from within the cluster. The digest of the latest commit looks like this:
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: tanzu-java-web-app
spec:
gitImplementation: go-git
ignore: '!.git'
interval: 1m0s
ref: {branch: main}
timeout: 20s
url: https://github.com/sample-accelerators/tanzu-java-web-app
status:
artifact:
checksum: 375c2daee5fc8657c5c5b49711a8e94d400994d7
lastUpdateTime: "2022-04-07T15:02:30Z"
path: gitrepository/default/tanzu-java-web-app/d85df1fc.tar.gz
revision: main/d85df1fc28c6b86ca54bd613f55991645d3b257c
url: http://source-controller.flux-system.svc.cluster.local./gitrepository/default/tanzu-java-web-app/d85df1fc.tar.gz
conditions:
- lastTransitionTime: "2022-04-07T15:02:30Z"
message: 'Fetched revision: main/d85df1fc28c6b86ca54bd613f55991645d3b257c'
reason: GitOperationSucceed
status: "True"
type: Ready
observedGeneration: 1
Cartographer passes the artifact URL and revision to further components in the supply chain. Those components must consume the source code from an internal URL where a tarball with the source code can be fetched, without having to process any Git-specific details in multiple places.
You can pass the following parameters by using the workload object’s workload.spec.params
field to override the default behavior of the GitRepository
object created for keeping track of the changes to a repository:
gitImplementation
: name of the Git implementation (either libgit2
or go-git
) to fetch the source code.
gitops_ssh_secret
: name of the secret in the same namespace as the workload where credentials to fetch the repository can be found.
You can also customize the following parameters with defaults for the whole cluster. Do this by using properties for either tap-values.yaml
when installing supply chains by using Tanzu Application Platform profiles, or ootb-supply-chain-*-values.yml
when installing the OOTB packages individually):
git_implementation
: the same as gitImplementation
workload parametergitops.ssh_secret
: the same as gitops_ssh_secret
workload parameterYou can provide source code from a local directory; that is, from a directory in the developer’s file system. The tanzu
CLI provides two flags to specify the source code location in the file system and where the source code is pushed to as a container image:
--local-path
: path on the local file system to a directory of source code to build for the workload--source-image
: destination image repository where source code is staged before being builtThis way, whether the cluster the developer targets is local (a cluster in the developer’s machine) or not, the source code is made available by using a container image registry.
For example, if a developer has source code under the current directory (.
) and access to a repository in a container image registry, you can create a workload as follows:
tanzu apps workload create tanzu-java-web-app \
--app tanzu-java-web-app \
--type web \
--local-path . \
--source-image $REGISTRY/test
Publish source in "." to "REGISTRY-SERVER/REGISTRY-REPOSITORY"?
It may be visible to others who can pull images from that repository
Yes
Publishing source in "." to "REGISTRY-SERVER/REGISTRY-REPOSITORY"...
Published source
Create workload:
1 + |---
2 + |apiVersion: carto.run/v1alpha1
3 + |kind: Workload
4 + |metadata:
5 + | labels:
6 + | app.kubernetes.io/part-of: tanzu-java-web-app
7 + | apps.tanzu.vmware.com/workload-type: web
8 + | name: tanzu-java-web-app
9 + | namespace: default
10 + |spec:
11 + | source:
12 + | image: REGISTRY-SERVER/REGISTRY-REPOSITORY:latest@<digest>
Where:
REGISTRY-SERVER
is the container image registry.REGISTRY-REPOSITORY
is the repository in the container image registry.Both the cluster and the developer’s machine must be configured to properly provide credentials for accessing the container image registry where the local source code is published to.
The tanzu
CLI must push the source code to the container image registry indicated by --source-image
. To do so, the CLI must find the credentials, so the developer must configure their machine accordingly.
To ensure credentials are available, use docker
to make the necessary credentials available for the Tanzu CLI to perform the image push. Run:
docker login REGISTRY-SERVER -u REGISTRY-USERNAME -p REGISTRY-PASSWORD
Aside from the developer’s ability to push source code to the image registry, the cluster must also have the proper credentials, so it can pull that container image, unpack it, run tests, build the application, and so on.
To provide the cluster with the credentials, point the ServiceAccount used by the workload at the Kubernetes secret that contains the credentials.
If the registry that the developer targets is the same one for which credentials were provided while setting up the workload namespace, no further action is required. Otherwise, follow the same steps as recommended for the application image.
A workload specifies that source code must come from an image by setting workload.spec.source.image
to point at the registry provided by using --source-image
. Then, instead of having a GitRepository object created, an ImageRepository object is instantiated, with its specification filled in such a way to keep track of images pushed to the registry provided by the user.
Take the following workload as an example:
apiVersion: carto.run/v1alpha1
kind: Workload
metadata:
name: app
labels:
app.kubernetes.io/part-of: app
apps.tanzu.vmware.com/workload-type: web
spec:
source:
image: 10.188.0.3:5000/test:latest
Instead of a GitRepository
object, an ImageRepository
is created:
Workload/app
│
- ├─GitRepository/app
+ ├─ImageRepository/app
│
├─Image/app
│ ├─Build/app-build-1
│ │ └─Pod/app-build-1-build-pod
│ ├─PersistentVolumeClaim/app-cache
│ └─SourceResolver/app-source
│
├─PodIntent/app
│
├─ConfigMap/app
│
└─Runnable/app-config-writer
└─TaskRun/app-config-writer-2zj7w
└─Pod/app-config-writer-2zj7w-pod
ImageRepository
provides the same semantics as GitRepository
, except that it looks for source code in container image registries rather than Git repositories.