Skip to content

Commit

Permalink
Merge pull request #16 from AustrianDataLAB/dev
Browse files Browse the repository at this point in the history
feature: create run task implementation (#15)
  • Loading branch information
Sokadyn authored Jun 26, 2023
2 parents 4223efe + 433b53c commit 8cb68f9
Show file tree
Hide file tree
Showing 24 changed files with 645 additions and 112 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ jobs:
uses: ietf-tools/[email protected]
with:
token: ${{ github.token }}
patchAll: true
# fall back to dev because we want to have a valid semver
branch: ${{ fromJSON('{"main":"dev"}')[github.ref_name] || github.ref_name }}
branch: ${{ fromJSON('{"main":"main"}')[github.ref_name] || github.ref_name }}
noVersionBumpBehavior: current

- name: Set OPERATOR_VERSION
Expand Down Expand Up @@ -198,7 +199,7 @@ jobs:
with:
token: ${{ github.token }}
# calculate the changelog from the last tag to the current dev state
fromTag: ${{ fromJSON('{"main":"dev"}')[github.ref_name] || github.ref_name }}
fromTag: ${{ fromJSON('{"main":"main"}')[github.ref_name] || github.ref_name }}
toTag: ${{ env.CURRENT }}
# Create a new release on GitHub with the semantic OPERATOR_VERSION number
- name: Create Release
Expand Down
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ help: ## Display this help.
##@ Development

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

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

.PHONY: fmt
Expand Down Expand Up @@ -173,6 +175,8 @@ $(LOCALBIN):
## Tool Binaries
KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENUM_GEN ?= $(LOCALBIN)/go-enum
ENUM_GEN_VERSION ?= latest
ENVTEST ?= $(LOCALBIN)/setup-envtest

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

.PHONY: enum-gen
enum-gen: $(ENUM_GEN) ## Download enum-gen locally if necessary.
$(ENUM_GEN): $(LOCALBIN)
test -s $(LOCALBIN)/go-enum || GOBIN=$(LOCALBIN) go install github.com/abice/go-enum@$(ENUM_GEN_VERSION)

.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
Expand Down
41 changes: 19 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,25 @@ ExecDAT is a tool to execute data analysis tasks on Kubernetes. It is designed t

## Getting Started

You’ll need a Kubernetes cluster to run against. See k3d for a quick way to get a local cluster up and running.
**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
### Prerequisites

* operator-sdk
* container engine (docker, podman, ...)
* kubernetes cluster (minikube, k3d, ...)

### Test out the operator

```shell
make install
make run
```

### Run using OLM

```shell
operator-sdk olm install
operator-sdk run bundle-upgrade ghcr.io/austriandatalab/execdat-operator-bundle:v0.2.0
```

### Running on the cluster

Expand Down Expand Up @@ -47,33 +64,13 @@ UnDeploy the controller to the cluster:
make undeploy
```

## Contributing

// TODO(user): Add detailed information on how you would like others to contribute to this project

### How it works

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

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

### Test It Out

1. Install the CRDs into the cluster:

```sh
make install
```

2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running):

```sh
make run
```

**NOTE:** You can also run this in one step by running: `make install run`

### Modifying the API definitions

If you are editing the API definitions, generate the manifests such as CRs or CRDs using:
Expand Down
3 changes: 1 addition & 2 deletions api/v1alpha1/build_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ type BuildSpec struct {

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

//+kubebuilder:object:root=true
Expand Down
24 changes: 13 additions & 11 deletions api/v1alpha1/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"k8s.io/utils/pointer"
)

type PodSpecData struct {
type BuildPodSpecData struct {
INIT_SH string
Dockerfile string
ImageName string
ImageTag string
}

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

podSpec.RestartPolicy = kcore.RestartPolicyNever

Expand All @@ -27,22 +28,23 @@ func (build *Build) SetPodSpec(podSpec *kcore.PodSpec, podSpecData PodSpecData)
}
podSpec.Containers = []kcore.Container{
{
Name: "buildah",
Image: "quay.io/buildah/stable",
Command: []string{"/bin/bash", "-c", "--"},
Args: []string{"trap : TERM INT; echo \"$INIT_SH\" | bash"},
Name: "buildah",
Image: "quay.io/buildah/stable",
ImagePullPolicy: kcore.PullIfNotPresent,
Command: []string{"/bin/bash", "-c", "--"},
Args: []string{"trap : TERM INT; echo \"$INIT_SH\" | bash"},
Env: []kcore.EnvVar{
{Name: "INIT_SH", Value: podSpecData.INIT_SH},
{Name: "DOCKERFILE", Value: podSpecData.Dockerfile},
{Name: "INIT_SH", Value: buildPodSpecData.INIT_SH},
{Name: "DOCKERFILE", Value: buildPodSpecData.Dockerfile},
{Name: "BASE_IMAGE", Value: build.Spec.BaseImage},
{Name: "IMAGE_NAME", Value: podSpecData.ImageName},
// {Name: "IMAGE_TAG", Value: build.Spec.ImageTag},
{Name: "IMAGE_NAME", Value: buildPodSpecData.ImageName},
{Name: "IMAGE_TAG", Value: buildPodSpecData.ImageTag},
// {Name: "IMAGE_REGISTRY", Value: build.Spec.ImageRegistry},
// {Name: "IMAGE_REGISTRY_USER", Value: build.Spec.ImageRegistryUser},
// {Name: "IMAGE_REGISTRY_PASSWORD", Value: build.Spec.ImageRegistryPassword},
// {Name: "IMAGE_REGISTRY_INSECURE", Value: build.Spec.ImageRegistryInsecure},
// {Name: "IMAGE_REGISTRY_VERIFY_TLS", Value: build.Spec.ImageRegistryVerifyTLS},
{Name: "ENTRYPOINT", Value: build.Spec.SourceCode.Entrypoint},
{Name: "ENTRYPOINT", Value: build.Spec.SourceCode.EntryPoint},
{Name: "GIT_REPO", Value: build.Spec.SourceCode.URL},
{Name: "GIT_BRANCH", Value: build.Spec.SourceCode.Branch},
{Name: "BUILD_CMD", Value: build.Spec.SourceCode.BuildCMD},
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/enums.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package v1alpha1

// swagger:enum CurrentPhase
// ENUM(pending, building, running, buildComplete, runCompleted, failed)
type CurrentPhase string
77 changes: 77 additions & 0 deletions api/v1alpha1/enums_enum.go

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

8 changes: 4 additions & 4 deletions api/v1alpha1/generic_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ type SourceCodeSpec struct {
Dependencies DependenciesSpec `json:"dependencies,omitempty"`
DependencyCMD string `json:"dependencycmd,omitempty"`
BuildCMD string `json:"buildcmd,omitempty"`
Entrypoint string `json:"entrypoint"`
EntryPoint string `json:"entrypoint"`
}

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

type OutputDataSpec struct {
URL string `json:"url" description:"URL of the data repo of output data"`
DataPath string `json:"datapath" description:"Path to the data directory with output data, has to be a unix path."`
URL string `json:"url,omitempty" description:"URL of the data repo of output data"`
}
12 changes: 5 additions & 7 deletions api/v1alpha1/run_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,17 @@ type RunSpec struct {
// Important: Run "make" to regenerate code after modifying this file

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

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

//+kubebuilder:object:root=true
Expand Down
68 changes: 68 additions & 0 deletions api/v1alpha1/runner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package v1alpha1

import (
kcore "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
)

type RunPodSpecData struct {
INIT_SH string
ImageName string
ImageTag string
InputDataPath string
OutputDataPath string
}

// SetPodSpec sets the pod spec for the run
func (run *Run) SetPodSpec(podSpec *kcore.PodSpec, runPodSpecData RunPodSpecData) error {

podSpec.RestartPolicy = kcore.RestartPolicyNever

podSpec.Volumes = []kcore.Volume{
{
Name: "input",
VolumeSource: kcore.VolumeSource{
EmptyDir: &kcore.EmptyDirVolumeSource{},
},
},
{
Name: "output",
VolumeSource: kcore.VolumeSource{
EmptyDir: &kcore.EmptyDirVolumeSource{},
},
},
}

podSpec.Containers = []kcore.Container{
{
Name: "buildah",
Image: "harbor.caas-0013.dev.austrianopencloudcommunity.org/execdev/" + runPodSpecData.ImageName + ":" + runPodSpecData.ImageTag,
ImagePullPolicy: kcore.PullIfNotPresent,
Command: []string{"/bin/bash", "-c", "--"},
Args: []string{"trap : TERM INT; echo \"$INIT_SH\" | bash"},
TTY: true,
Stdin: true,
Env: []kcore.EnvVar{
{Name: "INIT_SH", Value: runPodSpecData.INIT_SH},
{Name: "MINIO_ENDPOINT", Value: "http://minio.single-minio.svc.cluster.local:9000"},
{Name: "MINIO_ACCESS_KEY", Value: "cache-user-1"},
{Name: "MINIO_SECRET_KEY", Value: "CACHE_USER_PASS_XYZ_123"},
{Name: "BUCKET_NAME", Value: "cache-bucket-1"},
{Name: "HOME", Value: "/tmp"},
},
SecurityContext: &kcore.SecurityContext{
RunAsUser: pointer.Int64(1000),
RunAsGroup: pointer.Int64(1000),
},
VolumeMounts: []kcore.VolumeMount{
{Name: "input", MountPath: runPodSpecData.InputDataPath},
{Name: "output", MountPath: runPodSpecData.OutputDataPath},
},
},
}
podSpec.SecurityContext = &kcore.PodSecurityContext{
RunAsUser: pointer.Int64(1000),
RunAsGroup: pointer.Int64(1000),
}
return nil
}
Loading

0 comments on commit 8cb68f9

Please sign in to comment.