Saving to storage.
New buildfile. Storing backups in storage.
This commit is contained in:
11
Dockerfile
11
Dockerfile
@@ -1,5 +1,6 @@
|
|||||||
FROM docker.io/library/golang:1.25.5-alpine AS builder
|
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.25.5-alpine AS builder
|
||||||
|
|
||||||
|
ARG TARGETARCH
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
@@ -8,13 +9,13 @@ RUN go mod download
|
|||||||
COPY . /build
|
COPY . /build
|
||||||
|
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build -o /blazena
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /blazena
|
||||||
|
|
||||||
|
|
||||||
FROM docker.io/library/alpine:3.3
|
FROM docker.io/library/alpine:3.23
|
||||||
RUN apk add openssh rsync --no-cache
|
RUN apk add openssh rsync btrfs-progs --no-cache
|
||||||
|
|
||||||
COPY --from=builder /blazena /
|
COPY --from=builder --chmod=+x /blazena /
|
||||||
EXPOSE 1234
|
EXPOSE 1234
|
||||||
ENV MODE=invalid
|
ENV MODE=invalid
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ type RegistryAuth struct {
|
|||||||
func GetConfig() Config {
|
func GetConfig() Config {
|
||||||
var cfg Config;
|
var cfg Config;
|
||||||
|
|
||||||
rawConfig, err := os.ReadFile("./config.json");
|
rawConfig, err := os.ReadFile("/config.json");
|
||||||
if err != nil{
|
if err != nil{
|
||||||
panic("Failed it load config file." + err.Error());
|
panic("Failed it load config file." + err.Error());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
FROM alpine:3
|
|
||||||
|
|
||||||
RUN mkdir -p /root/.ssh/
|
|
||||||
RUN apk add openssh rsync --no-cache
|
|
||||||
@@ -52,7 +52,6 @@ func createStorageContainer(Config cfg.Config, DockerClient *client.Client, sshS
|
|||||||
Type: mount.TypeBind,
|
Type: mount.TypeBind,
|
||||||
Source: Config.LocalBasePath,
|
Source: Config.LocalBasePath,
|
||||||
Target: "/volume",
|
Target: "/volume",
|
||||||
ReadOnly: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
//AutoRemove: true,
|
//AutoRemove: true,
|
||||||
|
|||||||
98
host/host.go
98
host/host.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -51,9 +52,10 @@ func Run(Config cfg.Config) {
|
|||||||
if !prepareService(Config, service, volume) {continue}
|
if !prepareService(Config, service, volume) {continue}
|
||||||
fmt.Println("Done!");
|
fmt.Println("Done!");
|
||||||
|
|
||||||
// Skiping Host Key Check is temporary.
|
storagePath, _ := generateStoragePath(Config, service.Node, volume, DockerClient);
|
||||||
|
fmt.Println(storagePath);
|
||||||
command := `rsync -avz --delete -e "ssh -i /ssh-key -p 2222 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/expected-host-key" \
|
command := `rsync -avz --delete -e "ssh -i /ssh-key -p 2222 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/expected-host-key" \
|
||||||
root@tasks.`+ Config.Constants.HelperServiceName +`:/volume/ /tmp/` + volume;
|
root@tasks.`+ Config.Constants.HelperServiceName +`:/volume/ ` +storagePath;
|
||||||
|
|
||||||
exec, err := DockerClient.ContainerExecCreate(context.Background(), Config.Constants.StorageContainerName, container.ExecOptions{
|
exec, err := DockerClient.ContainerExecCreate(context.Background(), Config.Constants.StorageContainerName, container.ExecOptions{
|
||||||
Cmd: []string{"sh", "-c", command},
|
Cmd: []string{"sh", "-c", command},
|
||||||
@@ -185,3 +187,95 @@ func addToTar(tw *tar.Writer, filename string, content string) error{
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createIfMissing(targetPath string, DockerClient *client.Client, cfg cfg.Config) error{
|
||||||
|
const cmd = `#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TARGET_PATH=$1
|
||||||
|
|
||||||
|
# Remove trailing slash
|
||||||
|
TARGET_PATH=${TARGET_PATH%/}
|
||||||
|
|
||||||
|
CURRENT=""
|
||||||
|
|
||||||
|
case "$TARGET_PATH" in
|
||||||
|
/*) CURRENT="/" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
OLD_IFS=$IFS
|
||||||
|
IFS='/'
|
||||||
|
|
||||||
|
for PART in $TARGET_PATH; do
|
||||||
|
[ -z "$PART" ] && continue
|
||||||
|
|
||||||
|
if [ "$CURRENT" = "/" ]; then
|
||||||
|
NEXT="${CURRENT}${PART}"
|
||||||
|
else
|
||||||
|
NEXT="${CURRENT}/${PART}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -e "$NEXT" ]; then
|
||||||
|
case "$PART" in
|
||||||
|
@*)
|
||||||
|
echo "Creating Btrfs subvolume: $NEXT"
|
||||||
|
btrfs subvolume create "$NEXT"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Creating directory: $NEXT"
|
||||||
|
mkdir "$NEXT"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
echo "Already exists: $NEXT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CURRENT="$NEXT"
|
||||||
|
done
|
||||||
|
|
||||||
|
IFS=$OLD_IFS`;
|
||||||
|
|
||||||
|
exec, err := DockerClient.ContainerExecCreate(context.Background(), cfg.Constants.StorageContainerName, container.ExecOptions{
|
||||||
|
Cmd: []string{"sh", "-c", cmd, "_", targetPath},
|
||||||
|
AttachStdout: true,
|
||||||
|
AttachStderr: true,
|
||||||
|
Tty: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic("Failed to create execute!"+err.Error());
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := DockerClient.ContainerExecAttach(context.Background(), exec.ID, container.ExecStartOptions{});
|
||||||
|
defer resp.Close();
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic("Failed to atach to exec!"+err.Error());
|
||||||
|
}
|
||||||
|
|
||||||
|
inspect, err := DockerClient.ContainerExecInspect(context.Background(), exec.ID);
|
||||||
|
|
||||||
|
if(inspect.ExitCode != 0){
|
||||||
|
fmt.Println("<resp>");
|
||||||
|
io.Copy(os.Stdout, resp.Reader);
|
||||||
|
fmt.Println("</resp>");
|
||||||
|
return errors.New("Execution did return non zero code!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateStoragePath(cfg cfg.Config, node string, volumeId string, DockerClient *client.Client) (string, error){
|
||||||
|
var path string;
|
||||||
|
path += "/volume";
|
||||||
|
|
||||||
|
path += "/@"+ node +"/@"+ volumeId;
|
||||||
|
|
||||||
|
err := createIfMissing(path, DockerClient, cfg);
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path, nil;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user