new parser
This commit is contained in:
@@ -22,7 +22,5 @@ setup(
|
|||||||
"ssh-tunnelier = sshtunnelier:main",
|
"ssh-tunnelier = sshtunnelier:main",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
install_requires=[
|
install_requires=["psutil", "pyyaml"],
|
||||||
"psutil", "pyyaml"
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from argparse import ArgumentError, ArgumentParser
|
|||||||
import psutil
|
import psutil
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
__version__ = "2024.03.02"
|
__version__ = "2025.03.30"
|
||||||
|
|
||||||
CONFDIR = os.path.expanduser("~/.config/ssh-tunnelier")
|
CONFDIR = os.path.expanduser("~/.config/ssh-tunnelier")
|
||||||
CONF_OLD = os.path.join(CONFDIR, "tunnels.json")
|
CONF_OLD = os.path.join(CONFDIR, "tunnels.json")
|
||||||
@@ -76,7 +76,7 @@ def args():
|
|||||||
default=None,
|
default=None,
|
||||||
action="store",
|
action="store",
|
||||||
type=str,
|
type=str,
|
||||||
help="Instant tunnel. Syntax: sshserver:localport:targethost:remoteport",
|
help="Instant tunnel. Syntax: sshserver:localport[:targethost][:remoteport][:options]",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--auto",
|
"--auto",
|
||||||
@@ -149,7 +149,7 @@ def config_edit(editor):
|
|||||||
subprocess.run([editor, CONF])
|
subprocess.run([editor, CONF])
|
||||||
|
|
||||||
|
|
||||||
def connect(name, config):
|
def connect(name, config, foreground=False):
|
||||||
if name not in config:
|
if name not in config:
|
||||||
raise ValueError("No such connection name")
|
raise ValueError("No such connection name")
|
||||||
|
|
||||||
@@ -163,9 +163,21 @@ def connect(name, config):
|
|||||||
conn_id = get_id(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}"
|
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)
|
kill_connection(name, config)
|
||||||
|
try:
|
||||||
subprocess.run(cmd)
|
subprocess.run(cmd)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
if not foreground:
|
||||||
list_connections(config, single=name)
|
list_connections(config, single=name)
|
||||||
|
|
||||||
|
|
||||||
@@ -217,6 +229,44 @@ def auto_connect(config):
|
|||||||
connect(name, 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():
|
def main():
|
||||||
opts = args()
|
opts = args()
|
||||||
config = load_config()
|
config = load_config()
|
||||||
@@ -229,8 +279,8 @@ def main():
|
|||||||
if opts.auto:
|
if opts.auto:
|
||||||
auto_connect(config)
|
auto_connect(config)
|
||||||
if opts.connect:
|
if opts.connect:
|
||||||
host, tunnels = parse_connect(opts.connect)
|
name, config = parse_connect(opts.connect)
|
||||||
connect_tunnel(host, tunnels)
|
connect(name, config, foreground=True)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
if opts.kill:
|
if opts.kill:
|
||||||
kill_connection(opts.name, config)
|
kill_connection(opts.name, config)
|
||||||
|
|||||||
Reference in New Issue
Block a user