Merge pull request #11 from OpenCHAMI/docker

Add Dockerfile, Makefile rule, Goreleaser, and Github action
This commit is contained in:
David Allen 2024-09-25 18:17:49 -06:00 committed by GitHub
commit 0d4b8e92fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 159 additions and 17 deletions

39
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: Release with goreleaser
on:
workflow_dispatch:
push:
tags:
- v*
permissions: write-all # Necessary for the generate-build-provenance action with containers
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.21
uses: actions/setup-go@v5
with:
go-version: 1.21
- name: Checkout
uses: actions/checkout@v4
with:
fetch-tags: 1
fetch-depth: 0
- name: Release with goreleaser
uses: goreleaser/goreleaser-action@v6
env:
GITHUB_TOKEN: ${{ github.token }}
with:
version: latest
args: release --clean
id: goreleaser
- name: Attest Binaries
uses: actions/attest-build-provenance@v1
with:
subject-path: '${{ github.workspace }}/dist/configurator_linux_amd64_v1/configurator'

42
.goreleaser.yaml Normal file
View file

@ -0,0 +1,42 @@
version: 2
before:
hooks:
- go mod download
builds:
- env:
- CGO_ENABLED=1
goos:
- linux
goarch:
- amd64
archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of uname.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
files:
- LICENSE
- CHANGELOG.md
- README.md
- configurator
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
release:
github:
name_template: "{{.Version}}"
prerelease: auto
mode: append

16
Dockerfile Normal file
View file

@ -0,0 +1,16 @@
FROM cgr.dev/chainguard/wolfi-base
RUN apk add --no-cache tini bash
RUN mkdir -p /configurator
RUN mkdir -p /configurator/lib
# nobody 65534:65534
USER 65534:65534
# copy the binary and all of the default plugins
COPY configurator /configurator/configurator
COPY lib/* /configurator/lib/*
CMD ["/configurator"]
ENTRYPOINT [ "/sbin/tini", "--" ]

View file

@ -1,35 +1,56 @@
# Unless set otherwise, the container runtime is Docker
DOCKER ?= docker
prog ?= configurator
git_tag := $(shell git describe --abbrev=0 --tags --always)
sources := main.go $(wildcard cmd/*.go)
plugin_source_prefix := pkg/generator/plugins
plugin_sources := $(filter-out %_test.go,$(wildcard $(plugin_source_prefix)/*/*.go))
plugin_binaries := $(addprefix lib/,$(patsubst %.go,%.so,$(notdir $(plugin_sources))))
# build everything at once
.PHONY: all
all: plugins exe test
# build the main executable to make configs
.PHONY: main driver binaries exe
main: exe
driver: exe
exe:
go build --tags=all -o configurator
binaries: exe plugins
exe: $(prog)
# build named executable from go sources
$(prog): $(sources)
go build --tags=all -o $(prog)
.PHONY: container
container: binaries
$(DOCKER) build . --build-arg --no-cache --pull --tag '$(prog):$(git_tag)-dirty'
.PHONY: container-testing
container-testing: binaries
$(DOCKER) build . --tag $(prog):testing
# build all of the generators into plugins
plugins:
.PHONY: plugins
plugins: $(plugin_binaries)
# how to make each plugin
lib/%.so: pkg/generator/plugins/%/*.go
mkdir -p lib
go build -buildmode=plugin -o lib/conman.so pkg/generator/plugins/conman/conman.go
go build -buildmode=plugin -o lib/coredhcp.so pkg/generator/plugins/coredhcp/coredhcp.go
go build -buildmode=plugin -o lib/dhcpd.so pkg/generator/plugins/dhcpd/dhcpd.go
go build -buildmode=plugin -o lib/dnsmasq.so pkg/generator/plugins/dnsmasq/dnsmasq.go
go build -buildmode=plugin -o lib/example.so pkg/generator/plugins/example/example.go
go build -buildmode=plugin -o lib/hostfile.so pkg/generator/plugins/hostfile/hostfile.go
go build -buildmode=plugin -o lib/powerman.so pkg/generator/plugins/powerman/powerman.go
go build -buildmode=plugin -o lib/syslog.so pkg/generator/plugins/syslog/syslog.go
go build -buildmode=plugin -o lib/warewulf.so pkg/generator/plugins/warewulf/warewulf.go
go build -buildmode=plugin -o $@ $<
docs:
go doc github.com/OpenCHAMI/cmd
go doc github.com/OpenCHAMI/pkg/configurator
# remove executable and all built plugins
.PHONY: clean
clean:
rm configurator
rm lib/*
rm -f configurator
rm -f lib/*
# run all of the unit tests
test:
.PHONY: test
test: $(prog) $(plugin_binaries)
go test ./tests/generate_test.go --tags=all

View file

@ -50,6 +50,30 @@ curl http://127.0.0.1:3334/generate?target=dnsmasq -H "Authorization: Bearer $AC
This will do the same thing as the `generate` subcommand, but remotely. The access token is only required if the `CONFIGURATOR_JWKS_URL` environment variable is set. The `ACCESS_TOKEN` environment variable passed to `curl` and it's corresponding CLI argument both expects a token as a JWT.
### Docker
New images can be built and tested using the `Dockerfile` provided in the project. However, the binary executable and the generator plugins must first be built before building the image since the Docker build copies the binary over. Therefore, build all of the binaries first by following the first section of ["Building and Usage"](#building-and-usage). If you run the `make docker`, this will be done for you. Otherwise, run the `docker build` command after building the executable and libraries.
```bash
docker build -t configurator:testing path/to/configurator/Dockerfile
# ...or
make docker
```
Keep in mind that all plugins included in the project are build in the `lib/` directory and copied from there. If you want to easily include your own external generator plugins, you can build it and copy the `lib.so` file to that location. Make sure that the `Generator` interface is implemented correct as described in the ["Creating Generator Plugins"](#creating-generator-plugins) or the plugin will not load. Additionally, the name string returned from the `GetName()` method is used for looking up the plugin after all plugins have been loaded by the main driver.
Alternatively, pull the latest existing image/container from the GitHub container repository.
```bash
docker pull ghcr.io/openchami/configurator:latest
```
Then, run the container similarly to the binary.
```
docker run ghcr.io/openchami/configurator:latest configurator generate --config config.yaml --target dnsmasq
```
### Creating Generator Plugins
The `configurator` uses generator plugins to define how config files are generated using a `Generator` interface. The interface is defined like so:
@ -64,7 +88,7 @@ type Generator interface {
}
```
A new plugin can be created by implementing the methods from interface and exporting a symbol with `Generator` as the name and the plugin struct as the type. The `GetName()` function returns the name that is used for looking up the corresponding template set in your config file. It can also be included in the templated files with the default plugins using the `{{ plugin_name }}` in your template. The `GetVersion()` and `GetDescription()` functions returns the version and description of the plugin which can be included in the templated files using `{{ plugin_version }}` and `{{ plugin_description }}` respectively with the default plugins. The `Generate` function is where the magic happens to build the config file from a template.
A new plugin can be created by implementing the methods from interface and exporting a symbol with `Generator` as the name and the plugin struct as the type. The `GetName()` function returns the name that is used for looking up the corresponding target set in your config file. It can also be included in the templated files with the default plugins using the `{{ plugin_name }}` in your template. The `GetVersion()` and `GetDescription()` functions returns the version and description of the plugin which can be included in the templated files using `{{ plugin_version }}` and `{{ plugin_description }}` respectively with the default plugins. The `Generate` function is where the magic happens to build the config file from a template.
```go
package main