wip: 2024.08.16 14:07:25

This commit is contained in:
Daylin Morgan 2024-08-16 14:07:25 -05:00
parent 7557f75579
commit 775b4ca6e7
Signed by: daylin
GPG key ID: 950D13E9719334AD
12 changed files with 203 additions and 24 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
result

View file

@ -9,16 +9,19 @@
{ nixpkgs, ... }: { nixpkgs, ... }:
let let
inherit (nixpkgs.lib) genAttrs; inherit (nixpkgs.lib) genAttrs;
forAllSystems = systems = [
f: "x86_64-linux"
genAttrs [ "x86_64-darwin"
"x86_64-linux" "aarch64-linux"
"x86_64-darwin" "aarch64-darwin"
"aarch64-linux" ];
"aarch64-darwin" forAllSystems = f: genAttrs systems (system: f (import nixpkgs { inherit system; }));
] (system: f nixpkgs.legacyPackages.${system});
in in
{ {
packages = forAllSystems (pkgs: rec {
default = pkgs.callPackage ./meta.nix {inherit tunnel;};
tunnel = pkgs.callPackage ./tunnel-go { };
});
devShells = forAllSystems (pkgs: { devShells = forAllSystems (pkgs: {
default = pkgs.mkShell { default = pkgs.mkShell {
packages = with pkgs; [ packages = with pkgs; [

30
meta.nix Normal file
View file

@ -0,0 +1,30 @@
{
lib,
stdenvNoCC,
# packages
tunnel,
...
}:stdenvNoCC.mkDerivation (finalAttrs: {
pname = "meta";
version = "unstable";
# src =
buildInputs = [
tunnel
];
phases = [ "installPhase"];
installPhase = ''
mkdir -p $out/bin
ln -s ${tunnel}/bin/tunnel $out/bin
'';
meta = {
description = "meta package for utils";
homepage = "https://git.dayl.in/daylin/utils";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ daylinmorgan ];
};
})

View file

@ -13,12 +13,9 @@ buildGoModule rec {
version = "unstable"; version = "unstable";
src = cleanSource ./.; src = cleanSource ./.;
vendorHash = ""; vendorHash = "sha256-PwZJMEVaPHqZs7bM+9XLxVA36GfV3EN6bja86hkfO90=";
nativeBuildInputs = [ nativeBuildInputs = [ installShellFiles makeWrapper ];
installShellFiles
makeWrapper
];
postInstall = '' postInstall = ''
installShellCompletion --cmd ${pname} \ installShellCompletion --cmd ${pname} \

View file

@ -2,11 +2,13 @@ package main
import ( import (
"fmt" "fmt"
"io/fs"
"log" "log"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"strings"
"github.com/bitfield/script"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -40,28 +42,47 @@ func tunnelUp() {
logFail(connectPort(), "failed to connect to host: %s with port: %d", host, port) logFail(connectPort(), "failed to connect to host: %s with port: %d", host, port)
} }
func tunnelDown() { logFail(deactivateSshControl(), "failed to disable ssh control %s", host) } func tunnelDown() {
logFail(deactivateSshControl(), "failed to disable ssh control %s", host)
}
func getControlSockets(files []fs.DirEntry) (ret []string) {
for _, f := range files {
if strings.HasPrefix(f.Name(), "control") {
ret = append(ret, f.Name())
}
}
return
}
func tunnelShow() { func tunnelShow() {
script.ListFiles("/home/daylin/.ssh").Stdout() files, err := os.ReadDir(sshDir)
if err != nil {
panic(err)
}
controls := getControlSockets(files)
fmt.Printf("%d active connections\n", len(controls))
if len(controls) > 0 {
fmt.Println("hosts:")
for _, c := range controls {
fmt.Printf(" %s\n", strings.Split(c, "-")[1])
}
}
} }
var ( var (
sshDir = filepath.Join(os.Getenv("HOME"), ".ssh")
rootCmd = &cobra.Command{Use: "tunnel", Short: "control ssh tunnels"} rootCmd = &cobra.Command{Use: "tunnel", Short: "control ssh tunnels"}
upCmd = genSubCmd("up hostname [flags]", "activate ssh tunnel", tunnelUp) upCmd = genSubCmd("up hostname [flags]", "activate ssh tunnel", tunnelUp)
downCmd = genSubCmd("down hostname [flags]", "deactivate ssh tunnel", tunnelDown) downCmd = genSubCmd("down hostname [flags]", "deactivate ssh tunnel", tunnelDown)
showCmd = &cobra.Command{Use: "show", Short: "show activate tunnels", Run: func(cmd *cobra.Command, args []string) { tunnelShow() }} showCmd = &cobra.Command{Use: "show", Short: "show activate tunnels", Run: func(cmd *cobra.Command, args []string) { tunnelShow() }}
) port uint64
host string
var (
port uint64
host string
) )
func init() { func init() {
rootCmd.CompletionOptions.HiddenDefaultCmd = true rootCmd.CompletionOptions.HiddenDefaultCmd = true
rootCmd.AddCommand(upCmd) rootCmd.AddCommand(upCmd, downCmd, showCmd)
rootCmd.AddCommand(downCmd)
rootCmd.AddCommand(showCmd)
upCmd.Flags().Uint64VarP(&port, "port", "p", 0, "port number") upCmd.Flags().Uint64VarP(&port, "port", "p", 0, "port number")
upCmd.MarkFlagRequired("port") upCmd.MarkFlagRequired("port")
} }

3
tunnel-nim/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
nimbledeps/
nimble.paths
nimble.develop

11
tunnel-nim/config.nims Normal file
View file

@ -0,0 +1,11 @@
# begin Nimble config (version 2)
--noNimblePath
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
# end Nimble config
task updateLock, "update nix lock.json":
exec "nimble lock -l"
exec "nix run 'github:daylinmorgan/nnl' -- nimble.lock -o:lock.json"

14
tunnel-nim/default.nix Normal file
View file

@ -0,0 +1,14 @@
{
lib,
buildNimPackage,
makeWrapper,
}:
buildNimPackage {
pname = "tunnel";
version = "unstable";
src = lib.cleanSource ./.;
lockFile = ./lock.json;
nativeBuildInputs = [ makeWrapper ];
doCheck = false;
}

16
tunnel-nim/lock.json Normal file
View file

@ -0,0 +1,16 @@
{
"depends": [
{
"method": "fetchzip",
"path": "/nix/store/5a5aafd2vb3yb39ha5hbz8im9al9shjg-source",
"rev": "0e7b3b3a1fa77c448d3681c5fdf85197844cb7e4",
"sha256": "1c5xdxmgvibbrkn53svawp3wbwb0ylg3fnzbpgiadgnnpz3cdixz",
"srcDir": "",
"url": "https://github.com/c-blake/cligen/archive/0e7b3b3a1fa77c448d3681c5fdf85197844cb7e4.tar.gz",
"subDir": "",
"packages": [
"cligen"
]
}
]
}

16
tunnel-nim/nimble.lock Normal file
View file

@ -0,0 +1,16 @@
{
"version": 2,
"packages": {
"cligen": {
"version": "1.7.3",
"vcsRevision": "0e7b3b3a1fa77c448d3681c5fdf85197844cb7e4",
"url": "https://github.com/c-blake/cligen.git",
"downloadMethod": "git",
"dependencies": [],
"checksums": {
"sha1": "5a082835594887c0fdaea17dbfd2d3a2e744a2a9"
}
}
},
"tasks": {}
}

52
tunnel-nim/tunnel.nim Normal file
View file

@ -0,0 +1,52 @@
import std/[os, osproc, sequtils, strformat, strutils, sugar]
import cligen
proc checkHost(host: seq[string]): string =
case host.len:
of 0: quit "expected hostname"
of 1: return host[0]
else: quit "expected one positinal argument"
proc check(name: string): bool =
(execCmd &"ssh -O check {name}") == 0
proc startSsh(name: string) =
discard execCmd &"ssh -M -f -N {name}"
proc activateTunnel(name: string, port: int): int =
execCmd &"""ssh -fNL "{port}:localhost:{port}" {name}"""
proc exitSsh(name: string):int =
execCmd &"ssh -O exit {name}"
proc up(port: int, host: seq[string]) =
## activate a tunnel
let name = checkHost host
echo "activating connection to", name
if not check(name):
startSsh(name)
quit activateTunnel(name, port)
proc down(host: seq[string]) =
## disable all tunnels
let name = checkHost host
echo "deactivating connection to", name
quit exitSsh(name)
proc show() =
## show active connections
let sshDir = (getEnv "HOME") / ".ssh"
let controllers =
collect(for _,p in walkDir(sshDir): p)
.map(extractFilename)
.filterIt(it.startsWith("control"))
echo &"{controllers.len} active connections"
if controllers.len == 0: quit 0
echo "hosts:"
echo controllers.mapIt(" " & it.split('-')[1]).join("\n")
const
hostUsage = "$command [flags] hostname\n${doc}Options:\n$options"
usage = "$command [flags]\n${doc}Options:\n$options"
dispatchMulti([up, usage=hostUsage], [down, usage=hostUsage], [show, usage=usage])

15
tunnel-nim/tunnel.nimble Normal file
View file

@ -0,0 +1,15 @@
# Package
version = "0.1.0"
author = "Daylin Morgan"
description = "A new awesome nimble package"
license = "MIT"
srcDir = "."
bin = @["tunnel"]
# Dependencies
requires "nim >= 2.0.8"
requires "cligen"