nixos/autodeploy/main.go

122 lines
2.9 KiB
Go

package main
import (
"errors"
"flag"
"os"
"os/exec"
"github.com/go-git/go-git/v5"
"k8s.io/klog"
)
var (
flagRemote string
flagLocalCheckout string
flagImageName string
flagTrigger string
)
func podmanImageExists(name string) bool {
cmd := exec.Command("podman", "image", "inspect", name)
err := cmd.Run()
if err == nil {
{
return true
}
}
if cmd.ProcessState == nil {
klog.Exitf("Failed to run podman: %v", err)
}
return false
}
func podmanBuildImage(name, source string) error {
cmd := exec.Command("podman", "build", "-t", name, source)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
func podmanTagImage(image, target string) error {
cmd := exec.Command("podman", "tag", image, target)
return cmd.Run()
}
func main() {
flag.StringVar(&flagRemote, "remote", "https://git.orga.cebula.camp/infra/site.git", "Git remote path")
flag.StringVar(&flagLocalCheckout, "local_checkout", "/tmp/ci", "Path to local Git checkout")
flag.StringVar(&flagImageName, "image_name", "git.orga.cebula.camp/infra/site", "Name of podman image to build")
flag.StringVar(&flagTrigger, "trigger", "", "Command to run after golden image was updated")
flag.Parse()
repo, err := git.PlainClone(flagLocalCheckout, false, &git.CloneOptions{
URL: flagRemote,
Progress: os.Stdout,
Depth: 1,
})
if err != nil {
if errors.Is(err, git.ErrRepositoryAlreadyExists) {
repo, err = git.PlainOpen(flagLocalCheckout)
if err != nil {
klog.Exitf("Repo open failed: %v", err)
}
} else {
klog.Exitf("Initial clone failed: %v", err)
}
}
wt, err := repo.Worktree()
if err != nil {
klog.Exitf("Getting worktree failed: %v", err)
}
err = wt.Pull(&git.PullOptions{
RemoteName: "origin",
ReferenceName: "refs/heads/main",
SingleBranch: true,
Force: true,
})
if err != nil {
if !errors.Is(err, git.NoErrAlreadyUpToDate) {
klog.Exitf("Pull failed: %v", err)
}
}
ref, err := repo.Head()
if err != nil {
klog.Exitf("Getting HEAD failed: %v", err)
}
klog.Infof("main at %s", ref.Hash())
imageName := flagImageName + ":" + ref.Hash().String()
goldenName := flagImageName + ":golden"
if podmanImageExists(imageName) {
klog.Infof("Image %s already exists, exiting", imageName)
return
}
klog.Infof("Building %s...", imageName)
if err := podmanBuildImage(imageName, flagLocalCheckout); err != nil {
klog.Exitf("Building %s failed: %v", imageName, err)
}
klog.Infof("Succesfully built %s, tagging as %s", imageName, goldenName)
if err := podmanTagImage(imageName, goldenName); err != nil {
klog.Exitf("Tagging %s failed: %v", goldenName)
}
if flagTrigger != "" {
cmd := exec.Command("sh", "-c", flagTrigger)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
klog.Exitf("Trigger failed: %v", err)
}
} else {
klog.Infof("Trigger not defined")
}
}