diff --git a/go.mod b/go.mod index 3a8cd56..5f31932 100644 --- a/go.mod +++ b/go.mod @@ -8,5 +8,6 @@ require ( github.com/gorilla/mux v1.8.0 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.8.1 + golang.org/x/mod v0.3.0 gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/go.sum b/go.sum index 2c51f3f..2e01590 100644 --- a/go.sum +++ b/go.sum @@ -186,6 +186,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/k8s/configmap.yaml b/k8s/configmap.yaml index 2f81bb6..7538529 100644 --- a/k8s/configmap.yaml +++ b/k8s/configmap.yaml @@ -5,6 +5,73 @@ metadata: app: zippo name: zippo-config data: - config: | + zippo.tmpl: | variant: fcos version: 1.1.0 + + passwd: + users: + - name: {{ .SSHUser }} + ssh_authorized_keys: + - {{ .SSHPubkey }} + + systemd: + units: + # Bootstrap service + - name: bootstrap.service + enabled: true + contents: | + [Unit] + Description=Bootstrap script + + # Make sure we have networking up and running + Wants=network-online.target + After=network-online.target + + # We run before `zincati.service` to avoid conflicting rpm-ostree transactions. + Before=zincati.service + ConditionPathExists=!/var/lib/%N.stamp + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/usr/local/bin/bootstrap.sh + ExecStart=/bin/touch /var/lib/%N.stamp + + [Install] + WantedBy=multi-user.target + dropins: + - name: boostrap-rpms.conf + contents: | + [Service] + Environment="BOOTSTRAP_RPMS=" + Environment="CNI_VERSION={{ .CNIVersion }}" + Environment="CRICTL_VERSION={{ .CRICtlVersion }}" + + + storage: + files: + - path: /etc/hostname + mode: 0644 + contents: + inline: | + {{ .Hostname }} + + # Bootstrap script + - path: /usr/local/bin/bootstrap.sh + mode: 0755 + contents: + inline: | + #!/bin/bash + set -euo pipefail + + # Disable swap + swapoff -a + + # Install package dependencies if needed + /usr/bin/rpm-ostree install --apply-live --allow-inactive --idempotent $BOOTSTRAP_RPMS + + # Install CNI, CRICTL + mkdir -p /opt/cni/bin + curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | tar -C /opt/cni/bin -xz + curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-amd64.tar.gz" | tar -C /usr/local/bin -xz \ No newline at end of file diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index 030a250..4cc7215 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -23,15 +23,21 @@ spec: - --ssh-user=core - --ssh-pubkey= - --k8s=v1.20.0 - - --template=/etc/zippo/zippo.yaml + - --template=/etc/zippo/templates/zippo.tmpl + - --config=/etc/zippo/config.yaml volumeMounts: - name: zippo-etc mountPath: /etc/zippo + - name: zippo-etc-template + mountPath: /etc/zippo/templates volumes: - name: zippo-etc + emptyDir: {} + - name: zippo-etc-template configMap: name: zippo-config items: - - key: config - - path: config.yaml + - key: zippo.tmpl + path: zippo.tmpl + \ No newline at end of file diff --git a/main.go b/main.go index 4c9683e..25bcf82 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( zippo "github.com/jan0ski/zippo/pkg" log "github.com/sirupsen/logrus" + "golang.org/x/mod/semver" ) var ( @@ -16,16 +17,18 @@ var ( k8sVersion string cniVersion string templatePath string + configPath string ) func init() { flag.StringVar(&listenAddr, "address", "0.0.0.0", "listen address of the server") - flag.IntVar(&listenPort, "port", 8080, "key to add to `authorized_hosts` for ssh access") + flag.IntVar(&listenPort, "port", 8080, "listen port of the server") flag.StringVar(&sshUser, "ssh-user", "core", "initial user available via ssh") flag.StringVar(&sshPubkey, "ssh-pubkey", "", "key to add to `authorized_hosts` for ssh access") - flag.StringVar(&k8sVersion, "k8s", "v1.20.14", "Kubernetes version to install") - flag.StringVar(&cniVersion, "cni-version", "v0.8.2", "CNI version to install") - flag.StringVar(&templatePath, "template", "/etc/zippo/config.tmpl", "path to Butane template") + flag.StringVar(&k8sVersion, "k8s-version", "v1.23.0", "Kubernetes version to install") + flag.StringVar(&cniVersion, "cni-version", "v1.0.0", "CNI version to install") + flag.StringVar(&templatePath, "template", "/etc/zippo/templates/config.tmpl", "path to Butane template to render") + flag.StringVar(&configPath, "config", "/etc/zippo/config.yaml", "path to place rendered config") flag.Parse() } @@ -42,16 +45,16 @@ type args struct { func main() { // Don't set `Hostname`, it's populated from the host header args := args{ - Hostname: "{{ .Hostname }}", - SSHUser: sshUser, - SSHPubkey: sshPubkey, - K8sVersion: k8sVersion, - CRICtlVersion: k8sVersion, + Hostname: "{{ .Hostname }}", + SSHUser: sshUser, + SSHPubkey: sshPubkey, + K8sVersion: k8sVersion, + // CRICTL only has major/minor releases + CRICtlVersion: semver.MajorMinor(k8sVersion) + ".0", CNIVersion: cniVersion, } // populate config file with rendered template - configPath := "/etc/zippo/config.yaml" template, err := zippo.Render(templatePath, args) if err != nil { log.Fatalf(err.Error())