Merge branch 'trigger-nixos-rebuild-from-deploymentagent' into 'poc-integration'
Trigger nixos rebuild from deploymentagent See merge request infektweb/glv5/hetzner-cloud-environment!1
This commit is contained in:
commit
3a336c2101
31
.gitlab-ci.yml
Normal file
31
.gitlab-ci.yml
Normal file
@ -0,0 +1,31 @@
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
stages:
|
||||
- build
|
||||
- release
|
||||
|
||||
variables:
|
||||
BUILD_IMAGE: registry.gitlab.com/infektweb/glv5/hetzner-cloud-environment/deploymentagent:$CI_COMMIT_REF_NAME
|
||||
RELEASE_IMAGE: registry.gitlab.com/infektweb/glv5/hetzner-cloud-environment/deploymentagent:latest
|
||||
|
||||
before_script:
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
|
||||
|
||||
build:
|
||||
stage: build
|
||||
tags: [shell]
|
||||
script:
|
||||
- cd deploymentagent/src/deploymentagent && docker build --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN --pull -t $BUILD_IMAGE .
|
||||
- docker push $BUILD_IMAGE
|
||||
|
||||
release:
|
||||
stage: release
|
||||
tags: [shell]
|
||||
script:
|
||||
- docker pull $BUILD_IMAGE
|
||||
- docker tag $BUILD_IMAGE $RELEASE_IMAGE
|
||||
- docker push $RELEASE_IMAGE
|
||||
only:
|
||||
- master
|
@ -4,17 +4,21 @@ WORKDIR /go/src/app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN apk add --no-cache openssh git && \
|
||||
git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/" && \
|
||||
mkdir /root/.ssh && \
|
||||
ssh-keyscan gitlab.com >> /root/.ssh/known_hosts
|
||||
RUN apk add --no-cache openssh git
|
||||
|
||||
ARG SSH_KEY
|
||||
ENV SSH_KEY=${SSH_KEY}
|
||||
ARG CI_JOB_TOKEN
|
||||
ENV CI_JOB_TOKEN=${CI_JOB_TOKEN}
|
||||
|
||||
RUN printf "$SSH_KEY" | base64 -d > /root/.ssh/id_rsa && chmod 600 /root/.ssh/id_rsa && \
|
||||
go build -o deploymentagent && \
|
||||
rm /root/.ssh/id_rsa
|
||||
RUN test -n "$SSH_KEY" && \
|
||||
{ mkdir /root/.ssh && ssh-keyscan gitlab.com >> /root/.ssh/known_hosts && printf "$SSH_KEY" | base64 -d > /root/.ssh/id_rsa && chmod 600 /root/.ssh/id_rsa && git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/"; } || true
|
||||
|
||||
RUN test -n "$CI_JOB_TOKEN" && \
|
||||
{ printf "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc; } || true
|
||||
|
||||
RUN go build -o deploymentagent && \
|
||||
rm -f /root/.ssh/id_rsa
|
||||
|
||||
FROM alpine:3.12
|
||||
|
||||
|
@ -5,17 +5,9 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
inputQueue *DeploymentQueue // queued
|
||||
processQueue *DeploymentQueue // deploying, failed, deployed
|
||||
)
|
||||
|
||||
func main() {
|
||||
server := newDeploymentAgentServer()
|
||||
|
||||
inputQueue = new(DeploymentQueue)
|
||||
processQueue = new(DeploymentQueue)
|
||||
|
||||
go processDeploymentSpecs(&podmanClient{}, &http.Client{Transport: socketHttpTransport}, "http://podman/v1.0.0/libpod")
|
||||
|
||||
if err := http.ListenAndServe(":5000", server); err != nil {
|
||||
|
@ -3,7 +3,9 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
@ -19,12 +21,20 @@ var (
|
||||
basicAuthUsername string
|
||||
basicAuthPassword string
|
||||
deploymentStateFile string
|
||||
nixosRebuildSocketUrl string
|
||||
inputQueue *DeploymentQueue // queued
|
||||
processQueue *DeploymentQueue // deploying, failed, deployed
|
||||
)
|
||||
|
||||
func init() {
|
||||
basicAuthUsername = settings.GetSetting("BASIC_AUTH_USERNAME", "default")
|
||||
basicAuthPassword = settings.GetSetting("BASIC_AUTH_PASSWORD", "default")
|
||||
deploymentStateFile = settings.GetSetting("DEPLOYMENT_STATE_FILE", "./guidelines.json")
|
||||
nixosRebuildSocketUrl = settings.GetSetting("NIXOS_REBUILD_SOCKET_URL", "localhost:4444")
|
||||
|
||||
inputQueue = new(DeploymentQueue)
|
||||
processQueue = new(DeploymentQueue)
|
||||
|
||||
}
|
||||
|
||||
type DeploymentAgentServer struct {
|
||||
@ -181,19 +191,28 @@ func processDeploymentSpecs(pc *podmanClient, hc *http.Client, url string) {
|
||||
for {
|
||||
time.Sleep(5 * time.Second)
|
||||
if len(inputQueue.GetAll()) > 0 {
|
||||
var err error
|
||||
|
||||
dequequedDeploymentSpec := inputQueue.Dequeue()
|
||||
processQueue.Enqueue(dequequedDeploymentSpec.Id, "deploying", "Deployment in progress", dequequedDeploymentSpec.DeploymentSpec)
|
||||
err := pc.pullImages(dequequedDeploymentSpec.DeploymentSpec, hc, url)
|
||||
|
||||
err = pc.pullImages(dequequedDeploymentSpec.DeploymentSpec, hc, url)
|
||||
if err != nil {
|
||||
processQueue.updateStatus(dequequedDeploymentSpec.Id, "failed", err.Error(), nil)
|
||||
processQueue.updateStatus(dequequedDeploymentSpec.Id, "failed", ("When pulling images with Podman: " + err.Error()), getDeploymentState())
|
||||
} else {
|
||||
err := mergeDeploymentState(dequequedDeploymentSpec.DeploymentSpec)
|
||||
if err != nil {
|
||||
processQueue.updateStatus(dequequedDeploymentSpec.Id, "failed", err.Error(), getDeploymentState())
|
||||
processQueue.updateStatus(dequequedDeploymentSpec.Id, "failed", ("When updating the deploymentstate file" + err.Error()), getDeploymentState())
|
||||
} else {
|
||||
err = triggerNixosRebuild()
|
||||
if err != nil {
|
||||
processQueue.updateStatus(dequequedDeploymentSpec.Id, "failed", ("When triggering nixos-rebuild with Systemd: " + err.Error()), getDeploymentState())
|
||||
} else {
|
||||
processQueue.updateStatus(dequequedDeploymentSpec.Id, "deployed", "Deployment successful", getDeploymentState())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(processQueue.GetAll())
|
||||
}
|
||||
}
|
||||
@ -230,3 +249,27 @@ func mergeDeploymentState(deploymentSpec DeploymentSpec) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// triggerNixosRebuild connects to the activation socket of a
|
||||
// systemd unit which will trigger the nixos-rebuild unit.
|
||||
// The connection will be kept open and closed as soon as the
|
||||
// build has been completed, however, there is no way of
|
||||
// knowing whether there has been an error in the build phase
|
||||
// and thus the switch has not been applied.
|
||||
func triggerNixosRebuild() error {
|
||||
data := make([]byte, 1)
|
||||
|
||||
c, err := net.Dial("tcp", nixosRebuildSocketUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := c.Read(data); err == io.EOF {
|
||||
fmt.Println("nixos-rebuild switch has finished")
|
||||
c.Close()
|
||||
} else {
|
||||
c.Close()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -23,9 +23,29 @@
|
||||
# `systemctl start nixos-rebuild` := `nixos-rebuild switch`
|
||||
systemd.services.nixos-rebuild = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
postStart = "systemctl stop socket-nixos-rebuild-trigger.service && systemctl restart socket-nixos-rebuild-trigger.socket";
|
||||
script = ''
|
||||
/run/current-system/sw/bin/nixos-rebuild switch -I nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs -I nixos-config=/etc/nixos/configuration.nix
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
systemd.services.socket-nixos-rebuild-trigger = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
};
|
||||
after = [ "socket-nixos-rebuild-trigger.socket" ];
|
||||
requires = [ "socket-nixos-rebuild-trigger.socket" ];
|
||||
script = ''
|
||||
systemctl start nixos-rebuild
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.sockets.socket-nixos-rebuild-trigger = {
|
||||
listenStreams = [ "0.0.0.0:4444" ];
|
||||
partOf = [ "socket-nixos-rebuild-trigger.service" ];
|
||||
wantedBy = [ "sockets.target" ];
|
||||
};
|
||||
|
||||
users.extraUsers.operator = {
|
||||
|
Loading…
Reference in New Issue
Block a user