Skip to content

Instantly share code, notes, and snippets.

@imjasonh
Created Mar 2, 2021
Embed
What would you like to do?
package main
import (
"bytes"
"log"
"strings"
"github.com/ghodss/yaml"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
namespace := "my-namespace"
taskName := "hello-world"
pipelineName := "hello-world-pipeline"
refstr := "gcr.io/kontaindotme/tektonbundle"
ref, err := name.ParseReference(refstr)
if err != nil {
log.Fatalf("Failed to parse as an OCI reference: %v", err)
}
task := &v1beta1.Task{
TypeMeta: metav1.TypeMeta{Kind: "Task", APIVersion: "tekton.dev/v1beta1"},
ObjectMeta: metav1.ObjectMeta{Name: taskName, Namespace: namespace},
Spec: v1beta1.TaskSpec{
Steps: []v1beta1.Step{{
Container: corev1.Container{Name: "hello", Image: "alpine"},
Script: "echo Hello",
}},
},
}
pipeline := &v1beta1.Pipeline{
TypeMeta: metav1.TypeMeta{Kind: "Pipeline", APIVersion: "tekton.dev/v1beta1"},
ObjectMeta: metav1.ObjectMeta{Name: pipelineName, Namespace: namespace},
Spec: v1beta1.PipelineSpec{
Tasks: []v1beta1.PipelineTask{{
Name: "hello-world",
TaskRef: &v1beta1.TaskRef{
Name: taskName,
Bundle: refstr,
},
}},
},
}
// Write the task and pipeline into an image to the registry in the proper format.
rawTask, err := yaml.Marshal(task)
if err != nil {
log.Fatalf("Failed to marshal task to yaml: %s", err)
}
rawPipeline, err := yaml.Marshal(pipeline)
if err != nil {
log.Fatalf("Failed to marshal task to yaml: %s", err)
}
img := empty.Image
taskLayer, err := tarball.LayerFromReader(bytes.NewBuffer(rawTask))
if err != nil {
log.Fatalf("Failed to create oci layer from task: %s", err)
}
pipelineLayer, err := tarball.LayerFromReader(bytes.NewBuffer(rawPipeline))
if err != nil {
log.Fatalf("Failed to create oci layer from pipeline: %s", err)
}
img, err = mutate.Append(img, mutate.Addendum{
Layer: taskLayer,
Annotations: map[string]string{
"dev.tekton.image.name": taskName,
"dev.tekton.image.kind": strings.ToLower(task.Kind),
"dev.tekton.image.apiVersion": task.APIVersion,
},
}, mutate.Addendum{
Layer: pipelineLayer,
Annotations: map[string]string{
"dev.tekton.image.name": pipelineName,
"dev.tekton.image.kind": strings.ToLower(pipeline.Kind),
"dev.tekton.image.apiVersion": pipeline.APIVersion,
},
})
if err != nil {
log.Fatalf("Failed to create an oci image from the task and pipeline layers: %s", err)
}
if err := remote.Write(ref, img, remote.WithAuthFromKeychain(authn.DefaultKeychain)); err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment