diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7503f4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +result +.direnv +*.raw +var/* diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1da9918 --- /dev/null +++ b/flake.lock @@ -0,0 +1,42 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1651007983, + "narHash": "sha256-GNay7yDPtLcRcKCNHldug85AhAvBpTtPEJWSSDYBw8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e10da1c7f542515b609f8dfbcf788f3d85b14936", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "utils": { + "locked": { + "lastModified": 1649676176, + "narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7bd729b --- /dev/null +++ b/flake.nix @@ -0,0 +1,32 @@ +{ + description = "A basic Go web server setup"; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, utils }: + utils.lib.eachSystem [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ] (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ + (final: prev: { + go = prev.go_1_18; + buildGoModule = prev.buildGo118Module; + }) + ]; + }; + version = builtins.substring 0 8 self.lastModifiedDate; + in { + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ go gopls gotools go-tools squashfsTools ]; + }; + }); +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..64da523 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module tulpa.dev/cadey/taildeck + +go 1.18 diff --git a/main.go b/main.go new file mode 100644 index 0000000..2f9ef02 --- /dev/null +++ b/main.go @@ -0,0 +1,114 @@ +package main + +import ( + "archive/tar" + "compress/gzip" + "flag" + "fmt" + "io" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" +) + +var ( + out = flag.String("out-dir", ".", "where to save squashfs images to") + tsTarballPath = flag.String("tailscale-tarball", "./var/tailscale_1.24.2_amd64.tgz", "path to tailscale tarball on disk") + distro = flag.String("distro", "arch", "distro to stamp into system extension") +) + +func main() { + flag.Parse() + + fin, err := os.Open(*tsTarballPath) + if err != nil { + log.Fatal(err) + } + + gzRdr, err := gzip.NewReader(fin) + if err != nil { + log.Fatal(err) + } + + tarFin := tar.NewReader(gzRdr) + + tmpDir, err := os.MkdirTemp("", "taildeck-builder") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(filepath.Join(tmpDir, "usr", "bin"), 0755) + os.MkdirAll(filepath.Join(tmpDir, "usr", "sbin"), 0755) + os.MkdirAll(filepath.Join(tmpDir, "usr", "lib", "systemd", "system"), 0755) + os.MkdirAll(filepath.Join(tmpDir, "usr", "lib", "extension-release.d"), 0755) + + for { + hdr, err := tarFin.Next() + if err != nil { + if err == io.EOF { + break + } + log.Fatal(err) + } + + log.Printf("%s (%s): %d bytes", hdr.Name, strconv.FormatInt(hdr.Mode, 8), hdr.Size) + + var fname string + + switch filepath.Base(hdr.Name) { + case "tailscale": + fname = filepath.Join(tmpDir, "usr", "bin", "tailscale") + case "tailscaled": + fname = filepath.Join(tmpDir, "usr", "sbin", "tailscaled") + case "tailscaled.service": + fname = filepath.Join(tmpDir, "usr", "lib", "systemd", "system", "tailscaled.service") + default: + continue + } + + fout, err := os.Create(fname) + if err != nil { + log.Fatal(err) + } + + _, err = io.Copy(fout, tarFin) + if err != nil { + log.Fatal(err) + } + + err = fout.Close() + if err != nil { + log.Fatal(err) + } + } + + fout, err := os.Create(filepath.Join(tmpDir, "usr", "lib", "extension-release.d", "extension-release.tailscale")) + if err != nil { + log.Fatal(err) + } + + fmt.Fprintln(fout, "SYSEXT_LEVEL=1.0") + fmt.Fprintf(fout, "ID=%s", *distro) + + err = fout.Close() + if err != nil { + log.Fatal(err) + } + + binPath, err := exec.LookPath("mksquashfs") + if err != nil { + log.Fatal(err) + } + + sp := strings.Split(filepath.Base(*tsTarballPath), "_") + cmd := exec.Command(binPath, tmpDir, fmt.Sprintf("tailscale_sysext_%s.raw", sp[1]), "-quiet", "-noappend", "-all-root", "-root-mode", "755", "-b", "1M", "-comp", "xz", "-Xdict-size", "100%") + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + log.Fatal(err) + } +} diff --git a/run.sh b/run.sh deleted file mode 100644 index 6a0ddba..0000000 --- a/run.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -TS_VER=1.22.0 -TS_ROOT="${HOME}/.local/share/tailscale" -TS_PATH="${TS_ROOT}/tailscale_${TS_VER}_amd64" - -mkdir -p ${TS_ROOT} -cd ${TS_ROOT} - -if [ ! -d "${TS_PATH}" ]; then - curl -o tailscale_1.22.0_amd64.tgz https://pkgs.tailscale.com/stable/tailscale_1.22.0_amd64.tgz - tar zxf tailscale_1.22.0_amd64.tgz -fi - -sudo systemctl stop tailscaled.service ||: -sudo systemd-run \ - --service-type=notify \ - --description="Tailscale node agent" \ - -u tailscaled.service \ - -p ExecStartPre="${HOME}/.local/share/tailscale/tailscale_1.22.0_amd64/tailscaled --cleanup" \ - -p ExecStopPost="${HOME}/.local/share/tailscale/tailscale_1.22.0_amd64/tailscaled --cleanup" \ - -p Restart=on-failure \ - -p RuntimeDirectory=tailscale \ - -p RuntimeDirectoryMode=0755 \ - -p StateDirectory=tailscale \ - -p StateDirectoryMode=0700 \ - -p CacheDirectory=tailscale \ - -p CacheDirectoryMode=0750 \ - "${HOME}/.local/share/tailscale/tailscale_1.22.0_amd64/tailscaled" \ - "--state=/var/lib/tailscale/tailscaled.state" \ - "--socket=/run/tailscale/tailscaled.sock" - -sudo ${TS_PATH}/tailscale up \ No newline at end of file diff --git a/var/.gitkeep b/var/.gitkeep new file mode 100644 index 0000000..e69de29