Skip to content
This repository was archived by the owner on Jun 7, 2021. It is now read-only.

feat: add a TaskRun to build a function runtime image #11

Merged
merged 2 commits into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 27 additions & 0 deletions Gopkg.lock

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

8 changes: 8 additions & 0 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (
knv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1"
knv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"

// Import tekton types
pipeline "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
_ "k8s.io/client-go/plugin/pkg/client/auth"

Expand Down Expand Up @@ -123,6 +126,11 @@ func main() {
os.Exit(1)
}

if err := pipeline.AddToScheme(mgr.GetScheme()); err != nil {
log.Error(err, "Can't register the tekton pipeline scheme")
os.Exit(1)
}

// Setup all Controllers
if err := controller.AddToManager(mgr); err != nil {
log.Error(err, "")
Expand Down
69 changes: 69 additions & 0 deletions deploy/build/js-function-build-task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: js-function-build-runtime
spec:
inputs:
params:
- name: FUNCTION_NAME
description: The name of the function being built
default: 'user-function'
- name: TLSVERIFY
description: Verify the TLS on the registry endpoint (default false)
default: 'false'
outputs:
resources:
- name: image
type: image
steps:
- name: copy-source
image: docker.io/alpine
command: ['cp', '-fpv', '/fn-source/index.js', '/fn-source/package.json', '/home/node/usr/']
volumeMounts:
- name: sourcedir
mountPath: /fn-source
- name: gen-source
mountPath: /home/node/usr
securityContext:
privileged: true
- name: generate
image: quay.io/openshift-pipeline/s2i
workingdir: '/home/node/usr'
command: ['s2i', 'build', '.', 'quay.io/lanceball/js-runtime', '--as-dockerfile', '/home/node/build/Dockerfile.gen']
volumeMounts:
- name: gen-source
mountPath: /home/node/usr
- name: buildpath
mountPath: /home/node/build
securityContext:
privileged: true
- name: build
image: quay.io/buildah/stable
workingdir: /home/node/build
command: ['buildah', 'bud', '--tls-verify=${inputs.params.TLSVERIFY}', '--layers', '-f', '/Dockerfile.gen', '-t', '${outputs.resources.image.url}', '.']
volumeMounts:
- name: varlibcontainers
mountPath: /var/lib/containers
- name: buildpath
mountPath: /home/node/build
securityContext:
privileged: true
- name: push
image: quay.io/buildah/stable
command: ['buildah', 'push', '--tls-verify=${inputs.params.TLSVERIFY}', '${outputs.resources.image.url}', 'docker://${outputs.resources.image.url}']
volumeMounts:
- name: varlibcontainers
mountPath: /var/lib/containers
securityContext:
privileged: true

volumes:
- name: varlibcontainers
emptyDir: {}
- name: gen-source
emptyDir: {}
- name: buildpath
emptyDir: {}
- name: sourcedir
configMap:
name: ${inputs.params.FUNCTION_NAME}
2 changes: 1 addition & 1 deletion deploy/operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
containers:
- name: js-function-operator
# Replace this with the built image name
image: docker.io/lanceball/js-function-operator:v0.0.2
image: quay.io/lanceball/js-function-operator:v0.0.2
command:
- js-function-operator
imagePullPolicy: Always
Expand Down
6 changes: 6 additions & 0 deletions deploy/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ rules:
- services
verbs:
- '*'
- apiGroups:
- tekton.dev
resources:
- tasks
verbs:
- '*'
- apiGroups:
- monitoring.coreos.com
resources:
Expand Down
79 changes: 64 additions & 15 deletions pkg/controller/jsfunction/jsfunction_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

pipeline "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
kneventing "knative.dev/eventing/pkg/apis/eventing/v1alpha1"
knv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1"
knv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
Expand Down Expand Up @@ -134,8 +135,19 @@ func (r *ReconcileJSFunction) Reconcile(request reconcile.Request) (reconcile.Re
return reconcile.Result{}, err
}

reqLogger.Info("Creating TaskRun for function build.")
build, err := r.buildForFunction(function)
if err != nil {
return reconcile.Result{}, err
}
err = r.client.Create(context.TODO(), build)
if err != nil {
reqLogger.Error(err, "Failed to create TaskRun for function build.", "Service.Namespace", build.Namespace, "ConfigMap.Name", build.Name)
return reconcile.Result{}, err
}

// Create service, mounting the config map
service, err := r.serviceForFunction(function, configMap.Name)
service, err := r.serviceForFunction(function, configMap.Name, runtimeImageForFunction(function))
if err != nil {
return reconcile.Result{}, err
}
Expand Down Expand Up @@ -216,6 +228,49 @@ func (r *ReconcileJSFunction) Reconcile(request reconcile.Request) (reconcile.Re
return reconcile.Result{}, nil
}

func (r *ReconcileJSFunction) buildForFunction(f *faasv1alpha1.JSFunction) (*pipeline.TaskRun, error) {
imageName := runtimeImageForFunction(f)
taskRun := &pipeline.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-build", f.Name),
Namespace: f.Namespace,
},
Spec: pipeline.TaskRunSpec{
ServiceAccount: "js-function-operator",
TaskRef: &pipeline.TaskRef{
Name: "js-function-build-runtime",
},
Inputs: pipeline.TaskRunInputs{
Params: []pipeline.Param{{
Name: "FUNCTION_NAME",
Value: pipeline.ArrayOrString{
Type: "string",
StringVal: f.Name,
},
}},
},
Outputs: pipeline.TaskRunOutputs{
Resources: []pipeline.TaskResourceBinding{
{
Name: "image",
ResourceSpec: &pipeline.PipelineResourceSpec{
Type: "image",
Params: []pipeline.ResourceParam{{
Name: "url",
Value: imageName,
}},
},
},
},
},
},
}
if err := controllerutil.SetControllerReference(f, taskRun, r.scheme); err != nil {
return nil, err
}
return taskRun, nil
}

func (r *ReconcileJSFunction) configMapWithFunction(f *faasv1alpha1.JSFunction) (*corev1.ConfigMap, error) {

data := map[string]string{"index.js": f.Spec.Func}
Expand All @@ -238,7 +293,7 @@ func (r *ReconcileJSFunction) configMapWithFunction(f *faasv1alpha1.JSFunction)
return configMap, nil
}

func (r *ReconcileJSFunction) serviceForFunction(f *faasv1alpha1.JSFunction, configMapName string) (*knv1alpha1.Service, error) {
func (r *ReconcileJSFunction) serviceForFunction(f *faasv1alpha1.JSFunction, configMapName string, imageName string) (*knv1alpha1.Service, error) {
service := &knv1alpha1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: f.Name,
Expand All @@ -252,7 +307,7 @@ func (r *ReconcileJSFunction) serviceForFunction(f *faasv1alpha1.JSFunction, con
},
Spec: knv1alpha1.RevisionSpec{
RevisionSpec: knv1beta1.RevisionSpec{
PodSpec: createPodSpec(f.Name, configMapName),
PodSpec: createPodSpec(f.Name, imageName),
},
},
},
Expand All @@ -269,25 +324,15 @@ func (r *ReconcileJSFunction) serviceForFunction(f *faasv1alpha1.JSFunction, con
return service, nil
}

func createPodSpec(functionName, configMapName string) corev1.PodSpec {
volumeName := fmt.Sprintf("%s-source", functionName)
func createPodSpec(functionName, imageName string) corev1.PodSpec {
return corev1.PodSpec{
Containers: []corev1.Container{{
Image: "docker.io/zroubalik/js-runtime",
Image: imageName,
Name: fmt.Sprintf("nodejs-%s", functionName),
Ports: []corev1.ContainerPort{{
ContainerPort: 8080,
}},
VolumeMounts: []corev1.VolumeMount{
{
Name: volumeName,
MountPath: "/home/node/usr",
},
},
}},
Volumes: []corev1.Volume{
createConfigMapVolume(volumeName, configMapName),
},
}
}

Expand Down Expand Up @@ -357,3 +402,7 @@ func (r *ReconcileJSFunction) subscriptionForFunction(f *faasv1alpha1.JSFunction

return subscription, nil
}

func runtimeImageForFunction(f *faasv1alpha1.JSFunction) string {
return fmt.Sprintf("image-registry.openshift-image-registry.svc:5000/%s/%s-runtime", f.Namespace, f.Name)
}