diff options
| author | a73x <[email protected]> | 2024-08-25 13:21:16 +0100 |
|---|---|---|
| committer | a73x <[email protected]> | 2024-08-25 13:50:50 +0100 |
| commit | d76ca9ec81086e486a50a4aa03126271a3e520de (patch) | |
| tree | a2ea33f9263bf3c0e0f8c7e03ee26378bbc67a9f | |
| parent | cc284379187796719bbc6e8e19ff6e0b7e5b4e62 (diff) | |
now with a go bashscript
and hooks
| -rw-r--r-- | Dockerfile | 19 | ||||
| -rw-r--r-- | README (renamed from README.md) | 0 | ||||
| -rw-r--r-- | go.mod | 3 | ||||
| -rw-r--r-- | main.go | 141 |
4 files changed, 160 insertions, 3 deletions
@@ -1,3 +1,15 @@ +FROM golang:1.23.0-alpine3.20 + +WORKDIR /usr/src/app + +# COPY go.mod go.sum ./ +COPY go.mod . +RUN go mod download && go mod verify + +COPY . . + +RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /usr/local/bin/app . + FROM alpine:latest # Install necessary packages @@ -35,13 +47,14 @@ RUN echo "PasswordAuthentication no" >> /etc/ssh/sshd_config # Set MOTD -run echo "Connection successful!" > /etc/motd +RUN echo "Connection successful!" > /etc/motd # Expose SSH port EXPOSE 22 -COPY git-wrapper.sh /usr/local/bin/git-wrapper -RUN chmod +x /usr/local/bin/git-wrapper +COPY --from=0 /usr/local/bin/app /usr/local/bin/git-wrapper +# COPY git-wrapper.sh /usr/local/bin/git-wrapper +# RUN chmod +x /usr/local/bin/git-wrapper # Copy the entrypoint script COPY entrypoint.sh /entrypoint.sh @@ -0,0 +1,3 @@ +module git.sr.ht/~a73x/git + +go 1.23.0 @@ -0,0 +1,141 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "syscall" +) + +var logger *log.Logger +var logf *os.File + +func main() { + var err error + logf, err = os.OpenFile("loggy.boi", + os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + log.Fatal(err) + } + + defer logf.Close() + + logger = log.New(logf, "", log.LstdFlags) + sshOriginalCommand := os.Getenv("SSH_ORIGINAL_COMMAND") + if sshOriginalCommand == "" { + log.Fatal("SSH_ORIGINAL_COMMAND is not set") + } + + if err := Run(sshOriginalCommand); err != nil { + logger.Fatal(err) + } +} + +type Mkdir func([]string) error + +func mkdir(path string) error { + return os.MkdirAll(path, 0755) +} + +func Run(sshCmd string) error { + parts := strings.Split(sshCmd, " ") + if len(parts) != 2 { + return fmt.Errorf("expected 2 args: %s", sshCmd) + } + + command := parts[0] + repo := parts[1] + + remmappedRepo := RemapRepoPath(repo, "repos") + // creates repos if they don't exist + if _, err := os.Stat(remmappedRepo); os.IsNotExist(err) { + if err := setupRepo(remmappedRepo); err != nil { + return fmt.Errorf("failed to setup repo: %v", err) + } + } + + bin, err := exec.LookPath(command) + if err != nil { + return fmt.Errorf("failed to lookup %s:%v", command, err) + } + + // Execute the git-shell command + return syscall.Exec(bin, []string{command, remmappedRepo}, os.Environ()) +} + +func setupRepo(repo string) error { + // Create the directory (and any necessary parent directories) + if err := mkdir(repo); err != nil { + return fmt.Errorf("failed to create directory: %v", err) + } + + cmd := exec.Command("git", "init", "--bare", "--initial-branch=main", repo) + cmd.Stdout = logf + cmd.Stderr = logf + if err := cmd.Run(); err != nil { + return fmt.Errorf("failed to run initialize git repository: %v", err) + } + + if err := writeDescriptionHook(repo); err != nil { + logger.Printf("failed to create description hook: %v\n", err) + } + + return nil +} + +// 'a73x/cgit.git' => repos/a73x/cgit.git +func RemapRepoPath(repo string, path string) string { + return filepath.Join(path, strings.Trim(repo, "'")) +} + +var descriptionHook = `#!/bin/bash + +BRANCH="main" +FILE=README +while read oldrev newrev ref +do + # only checking out the master (or whatever branch you would like to deploy) + if [ "$ref" = "refs/heads/$BRANCH" ]; + then + changed=$(git ls-tree $REV $FILE) + if [ -n $changed ]; then + echo "Ref $ref received. updating description" + git show HEAD:README | head -n1 > description + fi + else + echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server." + fi +done` + +func writeDescriptionHook(path string) error { + hooksDir := filepath.Join(path, "hooks") + scriptPath := filepath.Join(hooksDir, "post-receive") + err := os.MkdirAll(hooksDir, 0755) + if err != nil { + return fmt.Errorf("error creating hooks directory: %v", err) + } + + file, err := os.Create(scriptPath) + if err != nil { + return fmt.Errorf("error creating post-receive file: %v", err) + } + + defer file.Close() + + // Write the script to the file + _, err = file.WriteString(descriptionHook) + if err != nil { + return fmt.Errorf("error writing script to file: %v", err) + } + + // Set the file permissions to be executable + err = os.Chmod(scriptPath, 0755) + if err != nil { + return fmt.Errorf("error setting file permissions: %v", err) + } + + return nil +} |
