From f6f1f52bc1f72430d319c1c3f41a1de4d6fe311a Mon Sep 17 00:00:00 2001 From: Sergei Lukianov Date: Thu, 28 Sep 2023 15:07:20 -0700 Subject: [PATCH] Enable VLAB in CI (#20) --- .github/workflows/ci.yaml | 59 +++++++++++++++++++++++++++++++++++++++ cmd/hhfab/main.go | 11 +++++++- hack/vlab-test.sh | 13 +++++++++ pkg/fab/vlab/service.go | 6 +++- pkg/fab/vlab/vm.go | 41 +++++++++++++++++++++------ 5 files changed, 120 insertions(+), 10 deletions(-) create mode 100755 hack/vlab-test.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c7e0fb81..64dfd3e2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -105,6 +105,64 @@ jobs: with: limit-access-to-actor: true + vlab: + runs-on: ["vlab"] + # needs: + # - cache-tools + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: stable + cache: true + + - name: Setup git for private Go modules + env: + GH_ACCESS_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + + - name: Build hhfab + run: | + make hhfab + + - name: Login to ghcr.io + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to lab registry + uses: docker/login-action@v3 + with: + registry: m.l.hhdev.io:31000 + username: lab + password: ${{ secrets.LAB_REGISTRY_TOKEN }} + + - name: hhfab init and build + run: | + export XDG_CONFIG_HOME=$(pwd)/.config + export HHFAB_BASE_REPO=m.l.hhdev.io:31000/githedgehog + + bin/hhfab init -p vlab -v + bin/hhfab build -v + ls -lah .hhfab + + bin/hhfab vlab up -v --dry-run + sudo bin/hhfab vlab up -v --run-complete hack/vlab-test.sh + - name: Setup tmate session for debug + if: ${{ failure() && github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} + uses: mxschmitt/action-tmate@v3 + timeout-minutes: 30 + with: + limit-access-to-actor: true + publish: # runs-on: ["lab", "simple", "jammy"] runs-on: ubuntu-latest @@ -112,6 +170,7 @@ jobs: needs: # - cache-tools - build + - vlab steps: - name: Checkout repository diff --git a/cmd/hhfab/main.go b/cmd/hhfab/main.go index d8c153aa..6f166c77 100644 --- a/cmd/hhfab/main.go +++ b/cmd/hhfab/main.go @@ -267,6 +267,14 @@ func main() { Name: "compact", Usage: "run more lightweight vms, small risks", }, + &cli.BoolFlag{ + Name: "install-complete", + Usage: "run installer and complete vlab (for testing)", + }, + &cli.StringFlag{ + Name: "run-complete", + Usage: "run installer, run provided script and than complete vlab (for testing)", + }, }, Before: func(ctx *cli.Context) error { return setupLogger(verbose, brief) @@ -284,7 +292,8 @@ func main() { killStaleVMs := cCtx.Bool("kill-stale-vms") - return errors.Wrap(svc.StartServer(killStaleVMs, cCtx.Bool("compact")), "error starting vlab") + return errors.Wrap(svc.StartServer(killStaleVMs, cCtx.Bool("compact"), + cCtx.Bool("install-complete"), cCtx.String("run-complete")), "error starting vlab") }, }, { diff --git a/hack/vlab-test.sh b/hack/vlab-test.sh new file mode 100755 index 00000000..aab3a571 --- /dev/null +++ b/hack/vlab-test.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -ex + +function control { + bin/hhfab vlab ssh --vm control-1 PATH=/opt/bin "$@" +} + +control kubectl fabric vpc create --name vpc-1 --subnet 10.90.0.1/24 +control kubectl fabric vpc attach --vpc vpc-1 --conn server-1--mclag--switch-1--switch-2 +control kubectl fabric vpc attach --vpc vpc-1 --conn server-2--mclag--switch-1--switch-2 + +control kubectl get agent -o wide \ No newline at end of file diff --git a/pkg/fab/vlab/service.go b/pkg/fab/vlab/service.go index 4f6dbdb7..fceb8e3d 100644 --- a/pkg/fab/vlab/service.go +++ b/pkg/fab/vlab/service.go @@ -48,6 +48,8 @@ type Service struct { type Config struct { DryRun bool Compact bool + InstallComplete bool + RunComplete string Basedir string Wiring *wiring.Data ControlIgnition string @@ -173,8 +175,10 @@ func (svc *Service) checkForStaleVMs(ctx context.Context, killStaleVMs bool) err return nil } -func (svc *Service) StartServer(killStaleVMs bool, compact bool) error { +func (svc *Service) StartServer(killStaleVMs bool, compact bool, installComplete bool, runComplete string) error { svc.cfg.Compact = compact + svc.cfg.InstallComplete = installComplete + svc.cfg.RunComplete = runComplete for _, cmd := range RequiredCommands { _, err := exec.LookPath(cmd) diff --git a/pkg/fab/vlab/vm.go b/pkg/fab/vlab/vm.go index af9039e8..cb706daa 100644 --- a/pkg/fab/vlab/vm.go +++ b/pkg/fab/vlab/vm.go @@ -85,6 +85,10 @@ func (vm *VM) Run(ctx context.Context, eg *errgroup.Group) { func (vm *VM) RunVM(ctx context.Context) func() error { return func() error { + if vm.Cfg.DryRun { + return nil + } + // <-vm.TPMReady time.Sleep(3 * time.Second) // TODO please, no! @@ -171,10 +175,6 @@ func (vm *VM) RunVM(ctx context.Context) func() error { return errors.Errorf("error running control vm: no ssh port found") } - if vm.Cfg.DryRun { - return nil - } - return errors.Wrapf(execCmd(ctx, vm.Basedir, true, "qemu-system-x86_64", []string{}, args...), "error running vm") } } @@ -185,12 +185,12 @@ func (vm *VM) RunInstall(ctx context.Context) func() error { return nil } - if vm.Cfg.DryRun { + if vm.Installed.Is() { + slog.Debug("Control node is already installed", "name", vm.Name) return nil } - if vm.Installed.Is() { - slog.Debug("Control node is already installed", "name", vm.Name) + if vm.Cfg.DryRun { return nil } @@ -256,6 +256,27 @@ func (vm *VM) RunInstall(ctx context.Context) func() error { return errors.Wrapf(err, "error marking control node as installed") } + if vm.Cfg.InstallComplete { + // TODO do graceful shutdown + slog.Info("Exiting after control node installation as requested") + os.Exit(0) + } + + if vm.Cfg.RunComplete != "" { + slog.Info("Running script after control node installation as requested") + + err = execCmd(ctx, "", false, vm.Cfg.RunComplete, []string{ + "KUBECONFIG=" + filepath.Join(vm.Cfg.Basedir, "kubeconfig.yaml"), + }) + if err != nil { + return errors.Wrapf(err, "error running script after control node installation") + } + + // TODO do graceful shutdown + slog.Info("Exiting after script after control node installation as requested") + os.Exit(0) + } + return nil } @@ -271,6 +292,10 @@ func (vm *VM) RunInstall(ctx context.Context) func() error { func (vm *VM) RunTPM(ctx context.Context) func() error { return func() error { + if vm.Cfg.DryRun { + return nil + } + err := execCmd(ctx, vm.Basedir, true, "swtpm", []string{}, "socket", "--tpm2", "--tpmstate", "dir=tpm", "--ctrl", "type=unixio,path=tpm.sock.ctrl", "--server", "type=unixio,path=tpm.sock", "--pid", "file=tpm.pid", "--log", "level=1", "--flags", "startup-clear") @@ -492,7 +517,7 @@ func execCmd(ctx context.Context, basedir string, quiet bool, name string, env [ outputs := []io.Writer{logFile} - if !quiet { + if !quiet || slog.Default().Enabled(ctx, slog.LevelDebug) { outputs = append(outputs, os.Stdout) }