wip: 2024.08.16 14:07:25
This commit is contained in:
parent
7557f75579
commit
775b4ca6e7
12 changed files with 203 additions and 24 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
result
|
11
flake.nix
11
flake.nix
|
@ -9,16 +9,19 @@
|
|||
{ nixpkgs, ... }:
|
||||
let
|
||||
inherit (nixpkgs.lib) genAttrs;
|
||||
forAllSystems =
|
||||
f:
|
||||
genAttrs [
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
] (system: f nixpkgs.legacyPackages.${system});
|
||||
];
|
||||
forAllSystems = f: genAttrs systems (system: f (import nixpkgs { inherit system; }));
|
||||
in
|
||||
{
|
||||
packages = forAllSystems (pkgs: rec {
|
||||
default = pkgs.callPackage ./meta.nix {inherit tunnel;};
|
||||
tunnel = pkgs.callPackage ./tunnel-go { };
|
||||
});
|
||||
devShells = forAllSystems (pkgs: {
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
|
|
30
meta.nix
Normal file
30
meta.nix
Normal 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 ];
|
||||
};
|
||||
})
|
|
@ -13,12 +13,9 @@ buildGoModule rec {
|
|||
version = "unstable";
|
||||
|
||||
src = cleanSource ./.;
|
||||
vendorHash = "";
|
||||
vendorHash = "sha256-PwZJMEVaPHqZs7bM+9XLxVA36GfV3EN6bja86hkfO90=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
installShellFiles
|
||||
makeWrapper
|
||||
];
|
||||
nativeBuildInputs = [ installShellFiles makeWrapper ];
|
||||
|
||||
postInstall = ''
|
||||
installShellCompletion --cmd ${pname} \
|
||||
|
|
|
@ -2,11 +2,13 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/bitfield/script"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -40,28 +42,47 @@ func tunnelUp() {
|
|||
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() {
|
||||
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 (
|
||||
sshDir = filepath.Join(os.Getenv("HOME"), ".ssh")
|
||||
rootCmd = &cobra.Command{Use: "tunnel", Short: "control ssh tunnels"}
|
||||
upCmd = genSubCmd("up hostname [flags]", "activate ssh tunnel", tunnelUp)
|
||||
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() }}
|
||||
)
|
||||
|
||||
var (
|
||||
port uint64
|
||||
host string
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.CompletionOptions.HiddenDefaultCmd = true
|
||||
rootCmd.AddCommand(upCmd)
|
||||
rootCmd.AddCommand(downCmd)
|
||||
rootCmd.AddCommand(showCmd)
|
||||
rootCmd.AddCommand(upCmd, downCmd, showCmd)
|
||||
upCmd.Flags().Uint64VarP(&port, "port", "p", 0, "port number")
|
||||
upCmd.MarkFlagRequired("port")
|
||||
}
|
||||
|
|
3
tunnel-nim/.gitignore
vendored
Normal file
3
tunnel-nim/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
nimbledeps/
|
||||
nimble.paths
|
||||
nimble.develop
|
11
tunnel-nim/config.nims
Normal file
11
tunnel-nim/config.nims
Normal 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
14
tunnel-nim/default.nix
Normal 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
16
tunnel-nim/lock.json
Normal 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
16
tunnel-nim/nimble.lock
Normal 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
52
tunnel-nim/tunnel.nim
Normal 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
15
tunnel-nim/tunnel.nimble
Normal 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"
|
||||
|
||||
|
Loading…
Reference in a new issue