Skip to content

Commit 8cb68f9

Browse files
authored
Merge pull request #16 from AustrianDataLAB/dev
feature: create run task implementation (#15)
2 parents 4223efe + 433b53c commit 8cb68f9

24 files changed

+645
-112
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ jobs:
5555
uses: ietf-tools/[email protected]
5656
with:
5757
token: ${{ github.token }}
58+
patchAll: true
5859
# fall back to dev because we want to have a valid semver
59-
branch: ${{ fromJSON('{"main":"dev"}')[github.ref_name] || github.ref_name }}
60+
branch: ${{ fromJSON('{"main":"main"}')[github.ref_name] || github.ref_name }}
6061
noVersionBumpBehavior: current
6162

6263
- name: Set OPERATOR_VERSION
@@ -198,7 +199,7 @@ jobs:
198199
with:
199200
token: ${{ github.token }}
200201
# calculate the changelog from the last tag to the current dev state
201-
fromTag: ${{ fromJSON('{"main":"dev"}')[github.ref_name] || github.ref_name }}
202+
fromTag: ${{ fromJSON('{"main":"main"}')[github.ref_name] || github.ref_name }}
202203
toTag: ${{ env.CURRENT }}
203204
# Create a new release on GitHub with the semantic OPERATOR_VERSION number
204205
- name: Create Release

Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,13 @@ help: ## Display this help.
8686
##@ Development
8787

8888
.PHONY: manifests
89-
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
89+
manifests: controller-gen enum-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
90+
$(ENUM_GEN) --marshal --ptr -f api/**/enums.go
9091
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
9192

9293
.PHONY: generate
93-
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
94+
generate: controller-gen enum-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
95+
$(ENUM_GEN) --marshal --ptr -f api/**/enums.go
9496
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
9597

9698
.PHONY: fmt
@@ -173,6 +175,8 @@ $(LOCALBIN):
173175
## Tool Binaries
174176
KUSTOMIZE ?= $(LOCALBIN)/kustomize
175177
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
178+
ENUM_GEN ?= $(LOCALBIN)/go-enum
179+
ENUM_GEN_VERSION ?= latest
176180
ENVTEST ?= $(LOCALBIN)/setup-envtest
177181

178182
## Tool Versions
@@ -190,6 +194,11 @@ controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessar
190194
$(CONTROLLER_GEN): $(LOCALBIN)
191195
test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
192196

197+
.PHONY: enum-gen
198+
enum-gen: $(ENUM_GEN) ## Download enum-gen locally if necessary.
199+
$(ENUM_GEN): $(LOCALBIN)
200+
test -s $(LOCALBIN)/go-enum || GOBIN=$(LOCALBIN) go install github.com/abice/go-enum@$(ENUM_GEN_VERSION)
201+
193202
.PHONY: envtest
194203
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
195204
$(ENVTEST): $(LOCALBIN)

README.md

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,25 @@ ExecDAT is a tool to execute data analysis tasks on Kubernetes. It is designed t
88

99
## Getting Started
1010

11-
You’ll need a Kubernetes cluster to run against. See k3d for a quick way to get a local cluster up and running.
12-
**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
11+
### Prerequisites
12+
13+
* operator-sdk
14+
* container engine (docker, podman, ...)
15+
* kubernetes cluster (minikube, k3d, ...)
16+
17+
### Test out the operator
18+
19+
```shell
20+
make install
21+
make run
22+
```
23+
24+
### Run using OLM
25+
26+
```shell
27+
operator-sdk olm install
28+
operator-sdk run bundle-upgrade ghcr.io/austriandatalab/execdat-operator-bundle:v0.2.0
29+
```
1330

1431
### Running on the cluster
1532

@@ -47,33 +64,13 @@ UnDeploy the controller to the cluster:
4764
make undeploy
4865
```
4966

50-
## Contributing
51-
52-
// TODO(user): Add detailed information on how you would like others to contribute to this project
53-
5467
### How it works
5568

5669
This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)
5770

5871
It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/)
5972
which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster
6073

61-
### Test It Out
62-
63-
1. Install the CRDs into the cluster:
64-
65-
```sh
66-
make install
67-
```
68-
69-
2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running):
70-
71-
```sh
72-
make run
73-
```
74-
75-
**NOTE:** You can also run this in one step by running: `make install run`
76-
7774
### Modifying the API definitions
7875

7976
If you are editing the API definitions, generate the manifests such as CRs or CRDs using:

api/v1alpha1/build_types.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ type BuildSpec struct {
3636

3737
// BuildStatus defines the observed state of Build
3838
type BuildStatus struct {
39-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
40-
// Important: Run "make" to regenerate code after modifying this file
39+
CurrentPhase *CurrentPhase `json:"currentPhase"` //TODO: add fields of status and dataurls to kubectl get outputs
4140
}
4241

4342
//+kubebuilder:object:root=true

api/v1alpha1/builder.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import (
55
"k8s.io/utils/pointer"
66
)
77

8-
type PodSpecData struct {
8+
type BuildPodSpecData struct {
99
INIT_SH string
1010
Dockerfile string
1111
ImageName string
12+
ImageTag string
1213
}
1314

1415
// SetPodSpec sets the pod spec for the build
15-
func (build *Build) SetPodSpec(podSpec *kcore.PodSpec, podSpecData PodSpecData) error {
16+
func (build *Build) SetPodSpec(podSpec *kcore.PodSpec, buildPodSpecData BuildPodSpecData) error {
1617

1718
podSpec.RestartPolicy = kcore.RestartPolicyNever
1819

@@ -27,22 +28,23 @@ func (build *Build) SetPodSpec(podSpec *kcore.PodSpec, podSpecData PodSpecData)
2728
}
2829
podSpec.Containers = []kcore.Container{
2930
{
30-
Name: "buildah",
31-
Image: "quay.io/buildah/stable",
32-
Command: []string{"/bin/bash", "-c", "--"},
33-
Args: []string{"trap : TERM INT; echo \"$INIT_SH\" | bash"},
31+
Name: "buildah",
32+
Image: "quay.io/buildah/stable",
33+
ImagePullPolicy: kcore.PullIfNotPresent,
34+
Command: []string{"/bin/bash", "-c", "--"},
35+
Args: []string{"trap : TERM INT; echo \"$INIT_SH\" | bash"},
3436
Env: []kcore.EnvVar{
35-
{Name: "INIT_SH", Value: podSpecData.INIT_SH},
36-
{Name: "DOCKERFILE", Value: podSpecData.Dockerfile},
37+
{Name: "INIT_SH", Value: buildPodSpecData.INIT_SH},
38+
{Name: "DOCKERFILE", Value: buildPodSpecData.Dockerfile},
3739
{Name: "BASE_IMAGE", Value: build.Spec.BaseImage},
38-
{Name: "IMAGE_NAME", Value: podSpecData.ImageName},
39-
// {Name: "IMAGE_TAG", Value: build.Spec.ImageTag},
40+
{Name: "IMAGE_NAME", Value: buildPodSpecData.ImageName},
41+
{Name: "IMAGE_TAG", Value: buildPodSpecData.ImageTag},
4042
// {Name: "IMAGE_REGISTRY", Value: build.Spec.ImageRegistry},
4143
// {Name: "IMAGE_REGISTRY_USER", Value: build.Spec.ImageRegistryUser},
4244
// {Name: "IMAGE_REGISTRY_PASSWORD", Value: build.Spec.ImageRegistryPassword},
4345
// {Name: "IMAGE_REGISTRY_INSECURE", Value: build.Spec.ImageRegistryInsecure},
4446
// {Name: "IMAGE_REGISTRY_VERIFY_TLS", Value: build.Spec.ImageRegistryVerifyTLS},
45-
{Name: "ENTRYPOINT", Value: build.Spec.SourceCode.Entrypoint},
47+
{Name: "ENTRYPOINT", Value: build.Spec.SourceCode.EntryPoint},
4648
{Name: "GIT_REPO", Value: build.Spec.SourceCode.URL},
4749
{Name: "GIT_BRANCH", Value: build.Spec.SourceCode.Branch},
4850
{Name: "BUILD_CMD", Value: build.Spec.SourceCode.BuildCMD},

api/v1alpha1/enums.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package v1alpha1
2+
3+
// swagger:enum CurrentPhase
4+
// ENUM(pending, building, running, buildComplete, runCompleted, failed)
5+
type CurrentPhase string

api/v1alpha1/enums_enum.go

Lines changed: 77 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha1/generic_types.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ type SourceCodeSpec struct {
2424
Dependencies DependenciesSpec `json:"dependencies,omitempty"`
2525
DependencyCMD string `json:"dependencycmd,omitempty"`
2626
BuildCMD string `json:"buildcmd,omitempty"`
27-
Entrypoint string `json:"entrypoint"`
27+
EntryPoint string `json:"entrypoint"`
2828
}
2929

3030
type InputDataSpec struct {
31-
URL string `json:"url" description:"URL of the data repo of input data"`
32-
Type string `json:"type" description:"Type of the input data source, e.g. s3, git, http, https, etc."`
3331
DataPath string `json:"datapath" description:"Path to the data directory with input data, has to be a unix path."`
32+
URL string `json:"url" description:"URL of the data repo of input data"`
33+
Type string `json:"type,omitempty" description:"Type of the input data source, e.g. s3, git, http, https, etc."`
3434
TransformCMD string `json:"transformcmd,omitempty" description:"Command to transform the input data"`
3535
}
3636

3737
type OutputDataSpec struct {
38-
URL string `json:"url" description:"URL of the data repo of output data"`
3938
DataPath string `json:"datapath" description:"Path to the data directory with output data, has to be a unix path."`
39+
URL string `json:"url,omitempty" description:"URL of the data repo of output data"`
4040
}

api/v1alpha1/run_types.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,17 @@ type RunSpec struct {
2929
// Important: Run "make" to regenerate code after modifying this file
3030

3131
// Foo is an example field of Run. Edit run_types.go to remove/update
32-
Build BuildSpec `json:"build"`
33-
OutputData OutputDataSpec `json:"outputdata"`
34-
//+optional
35-
InputData InputDataSpec `json:"inputdata,omitempty"`
36-
Description string `json:"description,omitempty"`
32+
Build BuildSpec `json:"build"`
33+
OutputData OutputDataSpec `json:"outputdata,omitempty"`
34+
InputData InputDataSpec `json:"inputdata,omitempty"`
35+
Description string `json:"description,omitempty"`
3736
}
3837

3938
// RunStatus defines the observed state of Run
4039
type RunStatus struct {
4140
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
4241
// Important: Run "make" to regenerate code after modifying this file
43-
CurrentPhase string `json:"currentPhase"` //TODO: add fields of status and dataurls to kubectl get outputs
44-
Test string `json:"test"`
42+
CurrentPhase *CurrentPhase `json:"currentPhase"` //TODO: add fields of status and dataurls to kubectl get outputs
4543
}
4644

4745
//+kubebuilder:object:root=true

api/v1alpha1/runner.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package v1alpha1
2+
3+
import (
4+
kcore "k8s.io/api/core/v1"
5+
"k8s.io/utils/pointer"
6+
)
7+
8+
type RunPodSpecData struct {
9+
INIT_SH string
10+
ImageName string
11+
ImageTag string
12+
InputDataPath string
13+
OutputDataPath string
14+
}
15+
16+
// SetPodSpec sets the pod spec for the run
17+
func (run *Run) SetPodSpec(podSpec *kcore.PodSpec, runPodSpecData RunPodSpecData) error {
18+
19+
podSpec.RestartPolicy = kcore.RestartPolicyNever
20+
21+
podSpec.Volumes = []kcore.Volume{
22+
{
23+
Name: "input",
24+
VolumeSource: kcore.VolumeSource{
25+
EmptyDir: &kcore.EmptyDirVolumeSource{},
26+
},
27+
},
28+
{
29+
Name: "output",
30+
VolumeSource: kcore.VolumeSource{
31+
EmptyDir: &kcore.EmptyDirVolumeSource{},
32+
},
33+
},
34+
}
35+
36+
podSpec.Containers = []kcore.Container{
37+
{
38+
Name: "buildah",
39+
Image: "harbor.caas-0013.dev.austrianopencloudcommunity.org/execdev/" + runPodSpecData.ImageName + ":" + runPodSpecData.ImageTag,
40+
ImagePullPolicy: kcore.PullIfNotPresent,
41+
Command: []string{"/bin/bash", "-c", "--"},
42+
Args: []string{"trap : TERM INT; echo \"$INIT_SH\" | bash"},
43+
TTY: true,
44+
Stdin: true,
45+
Env: []kcore.EnvVar{
46+
{Name: "INIT_SH", Value: runPodSpecData.INIT_SH},
47+
{Name: "MINIO_ENDPOINT", Value: "http://minio.single-minio.svc.cluster.local:9000"},
48+
{Name: "MINIO_ACCESS_KEY", Value: "cache-user-1"},
49+
{Name: "MINIO_SECRET_KEY", Value: "CACHE_USER_PASS_XYZ_123"},
50+
{Name: "BUCKET_NAME", Value: "cache-bucket-1"},
51+
{Name: "HOME", Value: "/tmp"},
52+
},
53+
SecurityContext: &kcore.SecurityContext{
54+
RunAsUser: pointer.Int64(1000),
55+
RunAsGroup: pointer.Int64(1000),
56+
},
57+
VolumeMounts: []kcore.VolumeMount{
58+
{Name: "input", MountPath: runPodSpecData.InputDataPath},
59+
{Name: "output", MountPath: runPodSpecData.OutputDataPath},
60+
},
61+
},
62+
}
63+
podSpec.SecurityContext = &kcore.PodSecurityContext{
64+
RunAsUser: pointer.Int64(1000),
65+
RunAsGroup: pointer.Int64(1000),
66+
}
67+
return nil
68+
}

0 commit comments

Comments
 (0)