Skip to content

Commit

Permalink
feat: big renovation, upgrade to idiomatic go 1.21 and now create OCI…
Browse files Browse the repository at this point in the history
… archives
  • Loading branch information
dpeckett committed Jan 22, 2024
1 parent 1631c2a commit a31b0ee
Show file tree
Hide file tree
Showing 18 changed files with 184 additions and 150 deletions.
1 change: 1 addition & 0 deletions .earthlyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dist/
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ on:

jobs:
build-and-test:
runs-on: self-hosted
runs-on: ubuntu-latest

steps:
- uses: earthly/actions-setup@v1
with:
version: v0.7.15
version: v0.7.23

- name: Check Out Repo
uses: actions/checkout@v3
Expand All @@ -25,20 +25,20 @@ jobs:
- name: Build
run: |
earthly +generate
earthly +airgapify
earthly +build
- name: Test
run: earthly +test

release:
needs: build-and-test
if: startsWith(github.ref, 'refs/tags/')
runs-on: self-hosted
runs-on: ubuntu-latest

steps:
- uses: earthly/actions-setup@v1
with:
version: v0.7.15
version: v0.7.23

- name: Build
run: |
Expand Down
2 changes: 0 additions & 2 deletions .golangci.yaml

This file was deleted.

18 changes: 9 additions & 9 deletions Earthfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
VERSION 0.7
FROM golang:1.20-bookworm
FROM golang:1.21-bookworm
WORKDIR /app

all:
COPY (+airgapify/airgapify --GOARCH=amd64) ./dist/airgapify-linux-amd64
COPY (+airgapify/airgapify --GOARCH=arm64) ./dist/airgapify-linux-arm64
COPY (+airgapify/airgapify --GOOS=darwin --GOARCH=amd64) ./dist/airgapify-darwin-amd64
COPY (+airgapify/airgapify --GOOS=darwin --GOARCH=arm64) ./dist/airgapify-darwin-arm64
COPY (+build/airgapify --GOARCH=amd64) ./dist/airgapify-linux-amd64
COPY (+build/airgapify --GOARCH=arm64) ./dist/airgapify-linux-arm64
COPY (+build/airgapify --GOOS=darwin --GOARCH=amd64) ./dist/airgapify-darwin-amd64
COPY (+build/airgapify --GOOS=darwin --GOARCH=arm64) ./dist/airgapify-darwin-arm64
RUN cd dist && find . -type f -exec sha256sum {} \; >> ../checksums.txt
SAVE ARTIFACT ./dist/airgapify-linux-amd64 AS LOCAL dist/airgapify-linux-amd64
SAVE ARTIFACT ./dist/airgapify-linux-arm64 AS LOCAL dist/airgapify-linux-arm64
SAVE ARTIFACT ./dist/airgapify-darwin-amd64 AS LOCAL dist/airgapify-darwin-amd64
SAVE ARTIFACT ./dist/airgapify-darwin-arm64 AS LOCAL dist/airgapify-darwin-arm64
SAVE ARTIFACT ./checksums.txt AS LOCAL dist/checksums.txt

airgapify:
build:
ARG GOOS=linux
ARG GOARCH=amd64
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build --ldflags '-s' -o airgapify cmd/airgapify/main.go
RUN CGO_ENABLED=0 go build --ldflags '-s' -o airgapify cmd/main.go
SAVE ARTIFACT ./airgapify AS LOCAL dist/airgapify-${GOOS}-${GOARCH}

generate:
Expand All @@ -30,15 +30,15 @@ generate:
RUN controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./api/..."
RUN controller-gen crd output:crd:artifacts:config=dist paths="./api/..."
SAVE ARTIFACT ./api/v1alpha1/zz_generated.deepcopy.go AS LOCAL api/v1alpha1/zz_generated.deepcopy.go
SAVE ARTIFACT ./dist/airgapify.gpu-ninja.com_configs.yaml AS LOCAL dist/airgapify.gpu-ninja.com_configs.yaml
SAVE ARTIFACT ./dist/airgapify.pecke.tt_configs.yaml AS LOCAL dist/airgapify.pecke.tt_configs.yaml

tidy:
LOCALLY
RUN go mod tidy
RUN go fmt ./...

lint:
FROM golangci/golangci-lint:v1.54.2
FROM golangci/golangci-lint:v1.55.2
WORKDIR /app
COPY . ./
RUN golangci-lint run --timeout 5m ./...
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# airgapify

A little tool that will construct a Docker image archive from a set of Kubernetes manifests.
A little tool that will construct an OCI image archive from a set of Kubernetes manifests.

## Usage

To create an image archive from a directory containing Kubernetes manifests:
To create an OCI image archive from a directory containing Kubernetes manifests:

```shell
airgapify -f manifests/ -o images.tar.zst
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha1/config_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2023 Damian Peckett <damian@pecke.tt>.
* Copyright 2024 Damian Peckett <damian@pecke.tt>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
6 changes: 3 additions & 3 deletions api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2023 Damian Peckett <damian@pecke.tt>.
* Copyright 2024 Damian Peckett <damian@pecke.tt>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,7 @@
*/

// +kubebuilder:object:generate=true
// +groupName=airgapify.gpu-ninja.com
// +groupName=airgapify.pecke.tt
package v1alpha1

import (
Expand All @@ -26,7 +26,7 @@ import (

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "airgapify.gpu-ninja.com", Version: "v1alpha1"}
GroupVersion = schema.GroupVersion{Group: "airgapify.pecke.tt", Version: "v1alpha1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

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

76 changes: 49 additions & 27 deletions cmd/airgapify/main.go → cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2023 Damian Peckett <damian@pecke.tt>.
* Copyright 2024 Damian Peckett <damian@pecke.tt>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,17 +19,15 @@ package main

import (
"fmt"
"log/slog"
"os"

airgapifyv1alpha1 "github.com/dpeckett/airgapify/api/v1alpha1"
"github.com/dpeckett/airgapify/internal/archive"
"github.com/dpeckett/airgapify/internal/extractor"
"github.com/dpeckett/airgapify/internal/loader"
v1 "github.com/google/go-containerregistry/pkg/v1"
airgapifyv1alpha1 "github.com/gpu-ninja/airgapify/api/v1alpha1"
"github.com/gpu-ninja/airgapify/internal/archive"
"github.com/gpu-ninja/airgapify/internal/extractor"
"github.com/gpu-ninja/airgapify/internal/loader"
zaplogfmt "github.com/jsternberg/zap-logfmt"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
)
Expand All @@ -39,17 +37,18 @@ func init() {
}

func main() {
config := zap.NewProductionEncoderConfig()
logger := zap.New(zapcore.NewCore(
zaplogfmt.NewEncoder(config),
os.Stdout,
zap.NewAtomicLevelAt(zapcore.InfoLevel),
))
logger := slog.New(slog.NewTextHandler(os.Stderr, nil))

app := &cli.App{
Name: "airgapify",
Usage: "A little tool that will construct a Docker image archive from a set of Kubernetes manifests.",
Usage: "A little tool that will construct an OCI image archive from a set of Kubernetes manifests.",
Flags: []cli.Flag{
&cli.GenericFlag{
Name: "log-level",
Aliases: []string{"l"},
Usage: "Set the log level",
Value: fromLogLevel(slog.LevelInfo),
},
&cli.StringSliceFlag{
Name: "file",
Aliases: []string{"f"},
Expand All @@ -59,7 +58,7 @@ func main() {
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "Where to write the image archive.",
Usage: "Where to write the oci image archive (will be a tar.zst archive).",
Value: "images.tar.zst",
},
&cli.StringFlag{
Expand All @@ -72,18 +71,25 @@ func main() {
Usage: "Disable progress output.",
},
},
Action: func(cCtx *cli.Context) error {
objects, err := loader.LoadObjectsFromFiles(cCtx.StringSlice("file"))
Before: func(c *cli.Context) error {
logger = slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: (*slog.Level)(c.Generic("log-level").(*logLevelFlag)),
}))

return nil
},
Action: func(c *cli.Context) error {
objects, err := loader.LoadObjectsFromFiles(c.StringSlice("file"))
if err != nil {
return fmt.Errorf("failed to load objects: %w", err)
}

logger.Info("Loaded objects", zap.Int("count", len(objects)))
logger.Info("Loaded objects", "count", len(objects))

rules := extractor.DefaultRules

for _, obj := range objects {
if obj.GetAPIVersion() == "airgapify.gpu-ninja.com/v1alpha1" && obj.GetKind() == "Config" {
if obj.GetAPIVersion() == "airgapify.pecke.tt/v1alpha1" && obj.GetKind() == "Config" {
logger.Info("Found airgapify config")

var config airgapifyv1alpha1.Config
Expand All @@ -108,25 +114,25 @@ func main() {
}

if images.Len() > 0 {
logger.Info("Found image references", zap.Int("count", images.Len()))
logger.Info("Found image references", "count", images.Len())
}

options := &archive.Options{}

if cCtx.IsSet("no-progress") && cCtx.Bool("no-progress") {
if c.IsSet("no-progress") && c.Bool("no-progress") {
options.DisableProgress = true
}

if cCtx.IsSet("platform") {
options.Platform, err = v1.ParsePlatform(cCtx.String("platform"))
if c.IsSet("platform") {
options.Platform, err = v1.ParsePlatform(c.String("platform"))
if err != nil {
return fmt.Errorf("failed to parse platform: %w", err)
}
}

outputPath := cCtx.String("output")
outputPath := c.String("output")

if err := archive.Create(cCtx.Context, logger, outputPath, images, options); err != nil {
if err := archive.Create(c.Context, logger, outputPath, images, options); err != nil {
return fmt.Errorf("failed to create image archive: %w", err)
}

Expand All @@ -135,6 +141,22 @@ func main() {
}

if err := app.Run(os.Args); err != nil {
logger.Fatal("Failed to run application", zap.Error(err))
logger.Error("Failed to run application", "error", err)
os.Exit(1)
}
}

type logLevelFlag slog.Level

func fromLogLevel(l slog.Level) *logLevelFlag {
f := logLevelFlag(l)
return &f
}

func (f *logLevelFlag) Set(value string) error {
return (*slog.Level)(f).UnmarshalText([]byte(value))
}

func (f *logLevelFlag) String() string {
return (*slog.Level)(f).String()
}
2 changes: 1 addition & 1 deletion examples/config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: airgapify.gpu-ninja.com/v1alpha1
apiVersion: airgapify.pecke.tt/v1alpha1
kind: Config
metadata:
name: airgapify-config
Expand Down
25 changes: 12 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,50 +1,49 @@
module github.com/gpu-ninja/airgapify
module github.com/dpeckett/airgapify

go 1.20
go 1.21.0

require (
github.com/cheggaaa/pb/v3 v3.1.4
github.com/google/go-containerregistry v0.16.1
github.com/jsternberg/zap-logfmt v1.3.0
github.com/klauspost/compress v1.16.5
github.com/mholt/archiver/v3 v3.5.1
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7
go.uber.org/zap v1.25.0
k8s.io/apimachinery v0.28.1
k8s.io/client-go v0.28.1
sigs.k8s.io/controller-runtime v0.16.0
)

require (
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v24.0.0+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.0+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.9.1 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.11.0 // indirect
Expand Down
Loading

0 comments on commit a31b0ee

Please sign in to comment.