new parser
This commit is contained in:
@@ -22,7 +22,5 @@ setup(
|
||||
"ssh-tunnelier = sshtunnelier:main",
|
||||
]
|
||||
},
|
||||
install_requires=[
|
||||
"psutil", "pyyaml"
|
||||
],
|
||||
install_requires=["psutil", "pyyaml"],
|
||||
)
|
||||
|
||||
@@ -11,7 +11,7 @@ from argparse import ArgumentError, ArgumentParser
|
||||
import psutil
|
||||
import yaml
|
||||
|
||||
__version__ = "2024.03.02"
|
||||
__version__ = "2025.03.30"
|
||||
|
||||
CONFDIR = os.path.expanduser("~/.config/ssh-tunnelier")
|
||||
CONF_OLD = os.path.join(CONFDIR, "tunnels.json")
|
||||
@@ -76,7 +76,7 @@ def args():
|
||||
default=None,
|
||||
action="store",
|
||||
type=str,
|
||||
help="Instant tunnel. Syntax: sshserver:localport:targethost:remoteport",
|
||||
help="Instant tunnel. Syntax: sshserver:localport[:targethost][:remoteport][:options]",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--auto",
|
||||
@@ -149,7 +149,7 @@ def config_edit(editor):
|
||||
subprocess.run([editor, CONF])
|
||||
|
||||
|
||||
def connect(name, config):
|
||||
def connect(name, config, foreground=False):
|
||||
if name not in config:
|
||||
raise ValueError("No such connection name")
|
||||
|
||||
@@ -163,9 +163,21 @@ def connect(name, config):
|
||||
conn_id = get_id(name, config)
|
||||
|
||||
remote_cmd = f"nice /bin/bash -c 'for ((i=1;i<{MAGIC_TIME};i++)); do cut -f4 -d \" \" /proc/$PPID/stat | xargs kill -0 || exit ; sleep 60;done'; echo tunnelier {conn_id}"
|
||||
cmd = ["ssh", "-f", "-n", *options, *tunnels, host, remote_cmd]
|
||||
f_commands = (
|
||||
[
|
||||
"-f",
|
||||
]
|
||||
if not foreground
|
||||
else []
|
||||
)
|
||||
cmd = ["ssh", *f_commands, "-n", *options, *tunnels, host, remote_cmd]
|
||||
if not foreground:
|
||||
kill_connection(name, config)
|
||||
try:
|
||||
subprocess.run(cmd)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
if not foreground:
|
||||
list_connections(config, single=name)
|
||||
|
||||
|
||||
@@ -217,6 +229,44 @@ def auto_connect(config):
|
||||
connect(name, config)
|
||||
|
||||
|
||||
def parse_connect(connect_string):
|
||||
|
||||
if not ":" in connect_string:
|
||||
raise ValueError("See the connection string format")
|
||||
|
||||
element_count = connect_string.count(":")
|
||||
elements = connect_string.split(":")
|
||||
name = elements[0]
|
||||
lport = int(elements[1])
|
||||
rport = lport
|
||||
raddr = "localhost"
|
||||
options = ""
|
||||
|
||||
if element_count == 2:
|
||||
rport = int(elements[2])
|
||||
if element_count == 3:
|
||||
raddr = elements[2]
|
||||
rport = int(elements[3])
|
||||
if element_count == 4:
|
||||
raddr = elements[2]
|
||||
rport = int(elements[3])
|
||||
options = elements[4]
|
||||
config = {
|
||||
name: {
|
||||
"host": name,
|
||||
"options": options,
|
||||
"auto-connect": False,
|
||||
"tunnels": [
|
||||
{"local_port": lport, "remote_port": rport, "remote_address": raddr, "reverse": False, "comment": ""}
|
||||
],
|
||||
}
|
||||
}
|
||||
url = f"http://localhost:{lport}"
|
||||
remote = LOCALHOSTSYMBOL if raddr == "localhost" else raddr
|
||||
print(f" Parsed: {lport} → {remote}:{rport} {url}")
|
||||
return name, config
|
||||
|
||||
|
||||
def main():
|
||||
opts = args()
|
||||
config = load_config()
|
||||
@@ -229,8 +279,8 @@ def main():
|
||||
if opts.auto:
|
||||
auto_connect(config)
|
||||
if opts.connect:
|
||||
host, tunnels = parse_connect(opts.connect)
|
||||
connect_tunnel(host, tunnels)
|
||||
name, config = parse_connect(opts.connect)
|
||||
connect(name, config, foreground=True)
|
||||
sys.exit(0)
|
||||
if opts.kill:
|
||||
kill_connection(opts.name, config)
|
||||
|
||||
Reference in New Issue
Block a user