Skip to content

Commit

Permalink
feat(harness): add stackrun harness (#171)
Browse files Browse the repository at this point in the history
* initial commit for stackrun harness

* extend exec handling to support custom log sink and remotely cancellable context

* small refactoring

* add controller and executor to manage the execution of commands

* small refactor

* are pre/post run callbacks to update run/runstep status accordingly

* initialize custom log sink for all executables

* update console logs sink

* add dockerfile to build harness image

* simplify harness dockerfile

* update console writer

* add initial logic to gather terraform output and complete stack run

* refactor state/output management and add more code documentation

* go mod tidy

* use nonroot tag

* add app version to harness

* add initial harness cd workflow

* fix main branch name

* disable test dependency

* update gh action

* update gh action and fix gitignore

* update gh action

* update console client and gh action

* push initial harness images

* listen for stack run status changes to see if it was cancelled

* update gh action

* fix terraform harness dockerfile

* update gh action

* add packages write permissions

* fix nil pointer

* wait for the subroutines to complete before finishing

* add sleep command to harness image

* fix: make console writer thread-safe

* enforce exec to use the same writer for stdout/stderr to ensure proper output order

* refactor code and add some documentation

* simplify code and update docs/comments

* fix tf state marshalling

* do not try to use plan file if it does not exist

* fix lint

* fix agent build

* fix agent dockerfile

* update clientmock

---------

Co-authored-by: Lukasz Zajaczkowski <[email protected]>
Co-authored-by: michaeljguarino <[email protected]>
  • Loading branch information
3 people authored May 17, 2024
1 parent 9d3fb48 commit bbeb412
Show file tree
Hide file tree
Showing 58 changed files with 2,934 additions and 153 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- run: PATH=$PATH:$GOPATH/bin make build
- run: PATH=$PATH:$GOPATH/bin make agent
test:
name: Unit test
runs-on: ubuntu-latest
Expand Down
152 changes: 152 additions & 0 deletions .github/workflows/publish-harness.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
name: Publish Harness

on:
pull_request:
branches:
- "main"
push:
tags:
- 'v*.*.*'

env:
GOPATH: /home/runner/go/
GOPROXY: "https://proxy.golang.org"

jobs:
# TODO: Enable once some unit tests are added for harness
# test:
# name: Unit test
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: actions/setup-go@v4
# with:
# go-version-file: go.mod
# check-latest: true
# - run: PATH=$PATH:$GOPATH/bin make test

publish-harness-base:
name: Build and push harness base container
runs-on: ubuntu-20.04
# needs: [test]
permissions:
contents: 'read'
id-token: 'write'
packages: 'write'
outputs:
version: ${{ steps.meta.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: |
ghcr.io/pluralsh/stackrun-harness-base
docker.io/pluralsh/stackrun-harness-base
tags: |
type=semver,pattern={{version}},priority=1000
type=sha,priority=800
type=ref,event=pr,priority=600
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker
uses: docker/login-action@v3
with:
username: mjgpluralsh
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: "."
file: "./hack/harness/base.Dockerfile"
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ steps.meta.outputs.version }}
# TODO: Do we need that for harness?
# - name: slack webhook
# uses: 8398a7/action-slack@v3
# with:
# status: ${{ job.status }}
# fields: workflow,job,repo,message,commit,author
# env:
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} # required
# if: always()

publish-harness-terraform:
name: Build and push harness terraform container
runs-on: ubuntu-20.04
needs: [publish-harness-base]
env:
TERRAFORM_VERSION: 1.8.2
permissions:
contents: write
discussions: write
pull-requests: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: |
ghcr.io/pluralsh/stackrun-harness
docker.io/pluralsh/stackrun-harness
tags: |
type=semver,pattern={{version}},suffix=-terraform${{ env.TERRAFORM_VERSION }},priority=1000
type=sha,suffix=-terraform${{ env.TERRAFORM_VERSION }},priority=800
type=ref,event=pr,suffix=-terraform${{ env.TERRAFORM_VERSION }},priority=600
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker
uses: docker/login-action@v3
with:
username: mjgpluralsh
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: "."
file: "./hack/harness/terraform.Dockerfile"
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
TERRAFORM_IMAGE_TAG=${{ env.TERRAFORM_VERSION }}
HARNESS_BASE_IMAGE_REPO=ghcr.io/pluralsh/stackrun-harness-base
HARNESS_BASE_IMAGE_TAG=${{ needs.publish-harness-base.outputs.version }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ bin/
# vendor/

notes.md

# Harness
stackrun/**
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ COPY go.sum go.sum
RUN go mod download

# Copy the go source
COPY /cmd cmd/
COPY /cmd/agent cmd/agent
COPY /pkg pkg/
COPY /api api/
COPY /internal internal/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -a -o deployment-agent cmd/*
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -a -o deployment-agent cmd/agent/**

FROM alpine:3.18
WORKDIR /workspace

COPY --from=builder /workspace/deployment-agent .
USER 65532:65532
ENTRYPOINT ["/workspace/deployment-agent"]
ENTRYPOINT ["/workspace/deployment-agent"]
43 changes: 36 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,51 @@ genmock: mockery ## generates mocks before running tests

##@ Run

.PHONY: run
run: ## run
go run cmd/*
.PHONY: agent-run
agent-run: ## run agent
go run cmd/agent/**

##@ Build

.PHONY: build
build: ## build
go build -o bin/deployment-agent cmd/*
.PHONY: agent
agent: ## build agent
go build -o bin/deployment-agent cmd/agent/**

.PHONY: harness
harness: ## build stack run harness
go build -o bin/stack-run-harness cmd/harness/main.go

docker-build: ## build image
docker build -t ${IMG} .

docker-push: ## push image
docker push ${IMG}

.PHONY: docker-build-harness-base
docker-build-harness-base: ## build base docker harness image
docker build \
--build-arg=VERSION="0.0.0-dev" \
-t harness-base \
-f hack/harness/base.Dockerfile \
.

.PHONY: docker-build-harness-terraform
docker-build-harness-terraform: docker-build-harness-base ## build terraform docker harness image
docker build \
--build-arg=HARNESS_IMAGE_TAG="latest" \
-t harness \
-f hack/harness/terraform.Dockerfile \
.

.PHONY: docker-run-harness
docker-run-harness: docker-build-harness-terraform ## build and run terraform docker harness image
docker run \
harness:latest \
--v=5 \
--console-url=${PLURAL_CONSOLE_URL}/ext/gql \
--console-token=${PLURAL_DEPLOY_TOKEN} \
--stack-run-id=${PLURAL_STACK_RUN_ID}

velero-crds:
@curl -L $(VELERO_CHART_URL) --output velero.tgz
@tar zxvf velero.tgz velero/crds
Expand Down Expand Up @@ -140,4 +169,4 @@ echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef
endef
File renamed without changes.
9 changes: 5 additions & 4 deletions cmd/main.go → cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import (

templatesv1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1"
constraintstatusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1"
deploymentsv1alpha1 "github.com/pluralsh/deployment-operator/api/v1alpha1"
"github.com/pluralsh/deployment-operator/internal/controller"
"github.com/pluralsh/deployment-operator/pkg/client"
"github.com/pluralsh/deployment-operator/pkg/log"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -17,6 +13,11 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"

deploymentsv1alpha1 "github.com/pluralsh/deployment-operator/api/v1alpha1"
"github.com/pluralsh/deployment-operator/internal/controller"
"github.com/pluralsh/deployment-operator/pkg/client"
"github.com/pluralsh/deployment-operator/pkg/log"
)

var (
Expand Down
File renamed without changes.
Loading

0 comments on commit bbeb412

Please sign in to comment.