From 0b411dc9cfb8b79dd37543f2f304ffd53facfbd6 Mon Sep 17 00:00:00 2001 From: Christopher Hase Date: Mon, 1 Sep 2025 15:39:45 +0200 Subject: [PATCH] feat(edge-connect): add skeleton --- .github/workflows/go-tests.yml | 27 +++++++++ .gitignore | 3 + Dockerfile | 15 +++++ Makefile | 61 +++++++++++++++++++ config/config.go | 41 +++++++++++++ go.mod | 40 ++++++++++++ go.sum | 108 +++++++++++++++++++++++++++++++++ main.go | 58 ++++++++++++++++++ provider/provider.go | 103 +++++++++++++++++++++++++++++++ scripts/build-static.sh | 48 +++++++++++++++ scripts/make-release.sh | 56 +++++++++++++++++ testdata/provider.rc | 5 ++ 12 files changed, 565 insertions(+) create mode 100644 .github/workflows/go-tests.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 config/config.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 provider/provider.go create mode 100755 scripts/build-static.sh create mode 100755 scripts/make-release.sh create mode 100644 testdata/provider.rc diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml new file mode 100644 index 0000000..a98eb49 --- /dev/null +++ b/.github/workflows/go-tests.yml @@ -0,0 +1,27 @@ +name: Go Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + go-tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Golang + uses: actions/setup-go@v3 + with: + go-version-file: go.mod + + - run: go version + + - name: Run GARM Go Tests + run: make test \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b53f297 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin/ +release/ +build/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ae023b7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM docker.io/golang:alpine + +WORKDIR /root +USER root + +RUN apk add musl-dev gcc libtool m4 autoconf g++ make libblkid util-linux-dev git linux-headers mingw-w64-gcc + +RUN wget http://musl.cc/aarch64-linux-musl-cross.tgz -O /tmp/aarch64-linux-musl-cross.tgz && \ + tar --strip-components=1 -C /usr/local -xzf /tmp/aarch64-linux-musl-cross.tgz && \ + rm /tmp/aarch64-linux-musl-cross.tgz + +ADD ./scripts/build-static.sh /build-static.sh +RUN chmod +x /build-static.sh + +CMD ["/bin/sh"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..97fde96 --- /dev/null +++ b/Makefile @@ -0,0 +1,61 @@ +SHELL := bash + +ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +GOPATH ?= $(shell go env GOPATH) +GO ?= go + +IMAGE_TAG = garm-provider-build + +IMAGE_BUILDER=$(shell (which docker || which podman)) +USER_ID=$(shell (($(IMAGE_BUILDER) --version | grep -q podman) && echo "0" || id -u)) +USER_GROUP=$(shell (($(IMAGE_BUILDER) --version | grep -q podman) && echo "0" || id -g)) +GARM_PROVIDER_NAME := garm-provider-edge-connect + +default: build + +.PHONY : build build-static test install-lint-deps lint go-test fmt fmtcheck verify-vendor verify create-release-files release + +build: + @$(GO) build . + +clean: ## Clean up build artifacts + @rm -rf ./bin ./build ./release + +build-static: + @echo Building + $(IMAGE_BUILDER) build --tag $(IMAGE_TAG) . + mkdir -p build + $(IMAGE_BUILDER) run --rm -e GARM_PROVIDER_NAME=$(GARM_PROVIDER_NAME) -e USER_ID=$(USER_ID) -e USER_GROUP=$(USER_GROUP) -v $(PWD)/build:/build/output:z -v $(PWD):/build/$(GARM_PROVIDER_NAME):z -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt $(IMAGE_TAG) /build-static.sh + @echo Binaries are available in $(PWD)/build + +test: install-lint-deps verify go-test + +install-lint-deps: + @$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.63.4 + +lint: + @golangci-lint run --timeout=8m --build-tags testing + +go-test: + @$(GO) test -race -mod=vendor -tags testing -v $(TEST_ARGS) -timeout=15m -parallel=4 -count=1 ./... + +fmt: + @$(GO) fmt $$(go list ./...) + +fmtcheck: + @gofmt -l -s $$(go list ./... | sed -n 's/github.com\/cloudbase\/'$(GARM_PROVIDER_NAME)'\/\(.*\)/\1/p') | grep ".*\.go"; if [ "$$?" -eq 0 ]; then echo "gofmt check failed; please tun gofmt -w -s"; exit 1;fi + +verify-vendor: ## verify if all the go.mod/go.sum files are up-to-date + $(eval TMPDIR := $(shell mktemp -d)) + @cp -R ${ROOTDIR} ${TMPDIR} + @(cd ${TMPDIR}/$(GARM_PROVIDER_NAME) && ${GO} mod tidy) + @diff -r -u -q ${ROOTDIR} ${TMPDIR}/$(GARM_PROVIDER_NAME) >/dev/null 2>&1; if [ "$$?" -ne 0 ];then echo "please run: go mod tidy && go mod vendor"; exit 1; fi + @rm -rf ${TMPDIR} + +verify: verify-vendor lint fmtcheck + +##@ Release +create-release-files: + ./scripts/make-release.sh + +release: build-static create-release-files ## Create a release diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..84c61d4 --- /dev/null +++ b/config/config.go @@ -0,0 +1,41 @@ +// Copyright 2023 Cloudbase Solutions SRL +// +// 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 config + +import ( + "fmt" + + "github.com/BurntSushi/toml" +) + +// NewConfig returns a new Config +func NewConfig(cfgFile string) (*Config, error) { + var config Config + if _, err := toml.DecodeFile(cfgFile, &config); err != nil { + return nil, fmt.Errorf("error decoding config: %w", err) + } + + if err := config.Validate(); err != nil { + return nil, fmt.Errorf("error validating config: %w", err) + } + return &config, nil +} + +type Config struct { +} + +func (c *Config) Validate() error { + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b3921e6 --- /dev/null +++ b/go.mod @@ -0,0 +1,40 @@ +module edp.buildth.ing/DevFW-CICD/garm-provider-edge-connect + +go 1.24 + +require ( + github.com/BurntSushi/toml v1.5.0 + github.com/cloudbase/garm-provider-common v0.1.7 + github.com/invopop/jsonschema v0.13.0 + github.com/stretchr/testify v1.10.0 + github.com/xeipuuv/gojsonschema v1.2.0 + golang.org/x/crypto v0.40.0 +) + +require ( + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/golang-jwt/jwt/v5 v5.2.3 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/handlers v1.5.2 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/minio/sio v0.4.1 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..13a7e97 --- /dev/null +++ b/go.sum @@ -0,0 +1,108 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 h1:Wc1ml6QlJs2BHQ/9Bqu1jiyggbsSjramq2oUmp5WeIo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.0.0 h1:Kb8eVvjdP6kZqYnER5w/PiGCFp91yVgaxve3d7kCEpY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.0.0/go.mod h1:lYq15QkJyEsNegz5EhI/0SXQ6spvGfgwBH/Qyzkoc/s= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0 h1:qBlqTo40ARdI7Pmq+enBiTnejZk2BF+PHgktgG8k3r8= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0/go.mod h1:UmyOatRyQodVpp55Jr5WJmnkmVW4wKfo85uHFmMEjfM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudbase/garm-provider-common v0.1.7 h1:V0upTejFRDiyFBO4hhkMWmPtmRTguyOt/4i1u9/rfbg= +github.com/cloudbase/garm-provider-common v0.1.7/go.mod h1:2O51WbcfqRx5fDHyyJgIFq7KdTZZnefsM+aoOchyleU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= +github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= +github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/minio/sio v0.4.1 h1:EMe3YBC1nf+sRQia65Rutxi+Z554XPV0dt8BIBA+a/0= +github.com/minio/sio v0.4.1/go.mod h1:oBSjJeGbBdRMZZwna07sX9EFzZy+ywu5aofRiV1g79I= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI= +github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI= +github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..0af9cc2 --- /dev/null +++ b/main.go @@ -0,0 +1,58 @@ +// Copyright 2023 Cloudbase Solutions SRL +// +// 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 main + +import ( + "context" + "fmt" + "os" + "os/signal" + "syscall" + + "edp.buildth.ing/DevFW-CICD/garm-provider-edge-connect/provider" + "github.com/cloudbase/garm-provider-common/execution" +) + +var signals = []os.Signal{ + os.Interrupt, + syscall.SIGTERM, +} + +func main() { + + ctx, stop := signal.NotifyContext(context.Background(), signals...) + defer stop() + + executionEnv, err := execution.GetEnvironment() + if err != nil { + fmt.Fprintf(os.Stderr, "Error getting environment: %q", err) + os.Exit(1) + } + + prov, err := provider.NewEdgeConnectProvider(executionEnv.ProviderConfigFile, executionEnv.ControllerID) + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating provider: %q", err) + os.Exit(1) + } + + result, err := executionEnv.Run(ctx, prov) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to run command: %+v\n", err) + os.Exit(1) + } + if len(result) > 0 { + fmt.Fprint(os.Stdout, result) + } +} diff --git a/provider/provider.go b/provider/provider.go new file mode 100644 index 0000000..4cc265f --- /dev/null +++ b/provider/provider.go @@ -0,0 +1,103 @@ +// Copyright 2023 Cloudbase Solutions SRL +// +// 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 provider + +import ( + "context" + "fmt" + + "edp.buildth.ing/DevFW-CICD/garm-provider-edge-connect/config" + + execution "github.com/cloudbase/garm-provider-common/execution/v0.1.0" + "github.com/cloudbase/garm-provider-common/params" +) + +var Version = "v0.0.0-unknown" + +func NewEdgeConnectProvider(configPath, controllerID string) (execution.ExternalProvider, error) { + conf, err := config.NewConfig(configPath) + if err != nil { + return nil, fmt.Errorf("error loading config: %w", err) + } + return &edgeConnectProvider{ + controllerID: controllerID, + cfg: conf, + }, nil +} + +type edgeConnectProvider struct { + controllerID string + cfg *config.Config +} + +// CreateInstance creates a new compute instance in the provider. +func (a *edgeConnectProvider) CreateInstance(ctx context.Context, bootstrapParams params.BootstrapInstance) (params.ProviderInstance, error) { + instance := params.ProviderInstance{ + ProviderID: "", + Name: "", + OSType: "", + OSArch: "", + OSName: "", + OSVersion: "", + Status: "running", + } + + return instance, nil +} + +// Delete instance will delete the instance in a provider. +func (a *edgeConnectProvider) DeleteInstance(ctx context.Context, instance string) error { + return nil +} + +// GetInstance will return details about one instance. +func (a *edgeConnectProvider) GetInstance(ctx context.Context, instance string) (params.ProviderInstance, error) { + providerInstance := params.ProviderInstance{ + ProviderID: "", + Name: "", + OSType: "", + OSArch: "", + OSName: "", + OSVersion: "", + Status: "running", + } + + return providerInstance, nil +} + +// ListInstances will list all instances for a provider. +func (a *edgeConnectProvider) ListInstances(ctx context.Context, poolID string) ([]params.ProviderInstance, error) { + return nil, nil +} + +// RemoveAllInstances will remove all instances created by this provider. +func (a *edgeConnectProvider) RemoveAllInstances(ctx context.Context) error { + return nil +} + +// Stop shuts down the instance. +func (a *edgeConnectProvider) Stop(ctx context.Context, instance string, force bool) error { + return nil +} + +// Start boots up an instance. +func (a *edgeConnectProvider) Start(ctx context.Context, instance string) error { + return nil +} + +// GetVersion returns the version of the provider. +func (a *edgeConnectProvider) GetVersion(ctx context.Context) string { + return Version +} diff --git a/scripts/build-static.sh b/scripts/build-static.sh new file mode 100755 index 0000000..0f43582 --- /dev/null +++ b/scripts/build-static.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +GARM_PROVIDER_NAME=${GARM_PROVIDER_NAME:-garm-provider-edge-connect} +GARM_SOURCE="/build/$GARM_PROVIDER_NAME" +git config --global --add safe.directory /build/$GARM_PROVIDER_NAME +cd $GARM_SOURCE + +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +if [ ! -z "$GARM_REF" ] && [ "$GARM_REF" != "$CURRENT_BRANCH" ];then + git checkout $GARM_REF +fi + +cd $GARM_SOURCE + +OUTPUT_DIR="/build/output" +VERSION=$(git describe --tags --match='v[0-9]*' --dirty --always) +BUILD_DIR="$OUTPUT_DIR/$VERSION" + + +[ ! -d "$BUILD_DIR/linux" ] && mkdir -p "$BUILD_DIR/linux" +[ ! -d "$BUILD_DIR/windows" ] && mkdir -p "$BUILD_DIR/windows" + +export CGO_ENABLED=1 +USER_ID=${USER_ID:-$UID} +USER_GROUP=${USER_GROUP:-$(id -g)} + +# Garm +cd $GARM_SOURCE + +# Linux +GOOS=linux GOARCH=amd64 go build -mod vendor \ + -o $BUILD_DIR/linux/amd64/$GARM_PROVIDER_NAME \ + -tags osusergo,netgo,sqlite_omit_load_extension \ + -ldflags "-extldflags '-static' -s -w -X edp.buildth.ing/DevFW-CICD/garm-provider-edge-connect/provider.Version=$VERSION" . +GOOS=linux GOARCH=arm64 CC=aarch64-linux-musl-gcc go build \ + -mod vendor \ + -o $BUILD_DIR/linux/arm64/$GARM_PROVIDER_NAME \ + -tags osusergo,netgo,sqlite_omit_load_extension \ + -ldflags "-extldflags '-static' -s -w -X edp.buildth.ing/DevFW-CICD/garm-provider-edge-connect/provider.Version=$VERSION" . + +# Windows +GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-cc go build -mod vendor \ + -o $BUILD_DIR/windows/amd64/$GARM_PROVIDER_NAME.exe \ + -tags osusergo,netgo,sqlite_omit_load_extension \ + -ldflags "-s -w -X edp.buildth.ing/DevFW-CICD/garm-provider-edge-connect/provider.Version=$VERSION" . + +git checkout $CURRENT_BRANCH || true +chown $USER_ID:$USER_GROUP -R "$OUTPUT_DIR" diff --git a/scripts/make-release.sh b/scripts/make-release.sh new file mode 100755 index 0000000..5ad1d20 --- /dev/null +++ b/scripts/make-release.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +echo $GARM_REF +GARM_PROVIDER_NAME=${GARM_PROVIDER_NAME:-garm-provider-edge-connect} + +VERSION=$(git describe --tags --match='v[0-9]*' --dirty --always) +RELEASE="$PWD/release" + +[ ! -d "$RELEASE" ] && mkdir -p "$RELEASE" + +if [ ! -z "$GARM_REF" ]; then + VERSION=$(git describe --tags --match='v[0-9]*' --always $GARM_REF) +fi + +echo $VERSION + +if [ ! -d "build/$VERSION" ]; then + echo "missing build/$VERSION" + exit 1 +fi + +# Windows + +if [ ! -d "build/$VERSION/windows/amd64" ];then + echo "missing build/$VERSION/windows/amd64" + exit 1 +fi + +if [ ! -f "build/$VERSION/windows/amd64/$GARM_PROVIDER_NAME.exe" ];then + echo "missing build/$VERSION/windows/amd64/$GARM_PROVIDER_NAME.exe" + exit 1 +fi + +pushd build/$VERSION/windows/amd64 +zip $GARM_PROVIDER_NAME-windows-amd64.zip $GARM_PROVIDER_NAME.exe +sha256sum $GARM_PROVIDER_NAME-windows-amd64.zip > $GARM_PROVIDER_NAME-windows-amd64.zip.sha256 +mv $GARM_PROVIDER_NAME-windows-amd64.zip $RELEASE +mv $GARM_PROVIDER_NAME-windows-amd64.zip.sha256 $RELEASE +popd + +# Linux +OS_ARCHES=("amd64" "arm64") + +for arch in ${OS_ARCHES[@]};do + if [ ! -f "build/$VERSION/linux/$arch/$GARM_PROVIDER_NAME" ];then + echo "missing build/$VERSION/linux/$arch/$GARM_PROVIDER_NAME" + exit 1 + fi + + pushd build/$VERSION/linux/$arch + tar czf $GARM_PROVIDER_NAME-linux-$arch.tgz $GARM_PROVIDER_NAME + sha256sum $GARM_PROVIDER_NAME-linux-$arch.tgz > $GARM_PROVIDER_NAME-linux-$arch.tgz.sha256 + mv $GARM_PROVIDER_NAME-linux-$arch.tgz $RELEASE + mv $GARM_PROVIDER_NAME-linux-$arch.tgz.sha256 $RELEASE + popd +done diff --git a/testdata/provider.rc b/testdata/provider.rc new file mode 100644 index 0000000..433c204 --- /dev/null +++ b/testdata/provider.rc @@ -0,0 +1,5 @@ +export GARM_COMMAND="ListInstances" +export GARM_CONTROLLER_ID="f77082bb-7035-4494-934c-3df4dff82675" +export GARM_POOL_ID="93639d57-edce-4f8f-902c-b3701d2d0d1b" +export GARM_PROVIDER_CONFIG_FILE="/home/ubuntu/config.toml" +export GARM_INSTANCE_ID="garm-test"