Skip to content

Commit

Permalink
Add Tekton Task
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhuGongpu committed Jul 14, 2020
1 parent 4e3224f commit f845528
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 2 deletions.
3 changes: 2 additions & 1 deletion internal/cmdexport/orchestrators/gitlabci.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import (
"path"
"strings"

"sigs.k8s.io/kustomize/kyaml/yaml"

"github.com/GoogleContainerTools/kpt/internal/cmdexport/types"
"gopkg.in/yaml.v3"
)

// GitLabCi is a simplified representation of GitLab CI/CD Configuration.
Expand Down
3 changes: 2 additions & 1 deletion internal/cmdexport/orchestrators/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import (
"strings"
"testing"

"gotest.tools/assert"

"github.com/GoogleContainerTools/kpt/internal/cmdexport/types"
"github.com/GoogleContainerTools/kpt/internal/util/testutil"
"gotest.tools/assert"
)

type testCase struct {
Expand Down
143 changes: 143 additions & 0 deletions internal/cmdexport/orchestrators/tekton.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orchestrators

import (
"path"

"sigs.k8s.io/kustomize/kyaml/yaml"

"github.com/GoogleContainerTools/kpt/internal/cmdexport/types"
)

// TektonMetadata contains metadata to describe a resource object.
type TektonMetadata struct {
Name string `yaml:",omitempty"`
}

// TektonWorkspace represents a shared workspace.
type TektonWorkspace struct {
Name string `yaml:",omitempty"`
MountPath string `yaml:"mountPath,omitempty"`
}

// TektonTaskConfig contains necessary configurations of the TektonTask class.
type TektonTaskConfig struct {
*types.PipelineConfig
// Name specifies the name of the task.
Name string
}

// TektonTask represents a Task object in Tekton.
// @see https://github.com/tektoncd/pipeline/blob/master/docs/tasks.md
type TektonTask struct {
APIVersion string `yaml:"apiVersion,omitempty"`
Kind string `yaml:",omitempty"`
Metadata *TektonMetadata `yaml:",omitempty"`
Spec *TektonTaskSpec `yaml:",omitempty"`
}

func (task *TektonTask) Init(config *TektonTaskConfig) *TektonTask {
task.APIVersion = "tekton.dev/v1beta1"
task.Kind = "Task"
task.Metadata = &TektonMetadata{Name: config.Name}

volumeName := "docker-socket"
volumeMount := &TektonVolumeMount{
Name: volumeName,
MountPath: "/var/run/docker.sock",
}

workspaceRoot := "$(workspaces.source.path)"
args := []string{
"fn",
"run",
path.Join(workspaceRoot, config.Dir),
}
if len(config.FnPaths) > 0 {
for _, fnPath := range config.FnPaths {
args = append(
args,
"--fn-path",
path.Join(workspaceRoot, fnPath),
)
}
}

step := &TektonTaskStep{
Name: config.Name,
Image: KptImage,
Args: args,
VolumeMounts: []*TektonVolumeMount{volumeMount},
}

volume := &TektonVolume{
Name: volumeName,
HostPath: &TektonVolumeHostPath{
Path: "/var/run/docker.sock",
Type: "Socket",
},
}

workspace := &TektonWorkspace{
Name: "source",
MountPath: "/source",
}

task.Spec = &TektonTaskSpec{
Workspaces: []*TektonWorkspace{workspace},
Steps: []*TektonTaskStep{step},
Volumes: []*TektonVolume{volume},
}

return task
}

func (task *TektonTask) Generate() (out []byte, err error) {
return yaml.Marshal(task)
}

// TektonTaskSpec describes the spec of a Task object.
type TektonTaskSpec struct {
Workspaces []*TektonWorkspace `yaml:",omitempty"`
Steps []*TektonTaskStep `yaml:",omitempty"`
Volumes []*TektonVolume `yaml:",omitempty"`
}

// TektonTaskStep is a step in the Task spec.
type TektonTaskStep struct {
Name string `yaml:",omitempty"`
Image string `yaml:",omitempty"`
Args []string `yaml:",omitempty"`
VolumeMounts []*TektonVolumeMount `yaml:"volumeMounts,omitempty"`
}

// TektonVolumeMount mounts a volume to a path.
type TektonVolumeMount struct {
Name string `yaml:",omitempty"`
MountPath string `yaml:"mountPath,omitempty"`
}

// TektonVolume describes a mountable volume on the host.
type TektonVolume struct {
Name string `yaml:",omitempty"`
HostPath *TektonVolumeHostPath `yaml:"hostPath,omitempty"`
}

// TektonVolumeHostPath indicates the path and its file type of a file on the host.
type TektonVolumeHostPath struct {
Path string `yaml:",omitempty"`
Type string `yaml:",omitempty"`
}
158 changes: 158 additions & 0 deletions internal/cmdexport/orchestrators/tekton_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orchestrators

import (
"strings"
"testing"

"gotest.tools/assert"

"github.com/GoogleContainerTools/kpt/internal/cmdexport/types"
)

type tektonTaskTestCase struct {
description string
config *TektonTaskConfig
expected string
}

var tektonTaskTestCases = []tektonTaskTestCase{
{
description: "generate a tekton task",
config: &TektonTaskConfig{
PipelineConfig: &types.PipelineConfig{
Dir: "local-resources/",
},
Name: "run-kpt-functions",
},
expected: `
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: run-kpt-functions
spec:
workspaces:
- name: source
mountPath: /source
steps:
- name: run-kpt-functions
image: gongpu/kpt:latest
args:
- fn
- run
- $(workspaces.source.path)/local-resources
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
type: Socket
`,
},
{
description: "generate a tekton task with --fn-path",
config: &TektonTaskConfig{
PipelineConfig: &types.PipelineConfig{
Dir: "local-resources",
FnPaths: []string{"config/"},
},
Name: "run-kpt-functions",
},
expected: `
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: run-kpt-functions
spec:
workspaces:
- name: source
mountPath: /source
steps:
- name: run-kpt-functions
image: gongpu/kpt:latest
args:
- fn
- run
- $(workspaces.source.path)/local-resources
- --fn-path
- $(workspaces.source.path)/config
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
type: Socket
`,
},
{
description: "generate a tekton task with multiple --fn-path",
config: &TektonTaskConfig{
PipelineConfig: &types.PipelineConfig{
Dir: "local-resources",
FnPaths: []string{"config/gate-keeper.yaml", "config/label-namespace.yaml"},
},
Name: "run-kpt-functions",
},
expected: `
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: run-kpt-functions
spec:
workspaces:
- name: source
mountPath: /source
steps:
- name: run-kpt-functions
image: gongpu/kpt:latest
args:
- fn
- run
- $(workspaces.source.path)/local-resources
- --fn-path
- $(workspaces.source.path)/config/gate-keeper.yaml
- --fn-path
- $(workspaces.source.path)/config/label-namespace.yaml
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
type: Socket
`,
},
}

func TestTektonTask(t *testing.T) {
for i := range tektonTaskTestCases {
testCase := tektonTaskTestCases[i]

t.Run(testCase.description, func(t *testing.T) {
pipeline, _ := new(TektonTask).Init(testCase.config).Generate()

actual := string(pipeline)
expected := strings.TrimLeft(testCase.expected, "\n")

assert.Equal(t, expected, actual)
})
}
}

0 comments on commit f845528

Please sign in to comment.