[CRIU] [PATCH 1/3] p.haul: transform p.haul-ssh into python module and use it inside p.haul

Ruslan Kuprieiev kupruser at gmail.com
Sun Mar 8 12:38:44 PDT 2015


Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
---
 p.haul     |  14 +++++++
 p.haul-ssh | 130 -------------------------------------------------------------
 ssh.py     |  88 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+), 130 deletions(-)
 delete mode 100755 p.haul-ssh
 create mode 100644 ssh.py

diff --git a/p.haul b/p.haul
index 859ba18..e7dd318 100755
--- a/p.haul
+++ b/p.haul
@@ -5,6 +5,8 @@ import p_haul_iters as ph_iters
 import images
 import criu_api
 import xem_rpc
+import getpass
+import ssh
 
 # Usage idea
 # p.haul <type> <id> <destination>
@@ -30,8 +32,20 @@ parser.add_argument("--pid-root", help = "Path to tree's FS root")
 parser.add_argument("--force", help = "Don't do any sanity (CPU compat) checks", default = False, action = 'store_true')
 parser.add_argument("--port", help = "Port where to haul", type = int, default = xem_rpc.rpc_port)
 
+parser.add_argument("--no-ssh", help = "Don't use ssh", default = False, action = "store_true")
+parser.add_argument("--no-ssh-comp", help = "Don't use compression in ssh tunnel", default = False, action = 'store_true')
+parser.add_argument("--ssh-user", help = "Remote username (current user by default)", default = ssh.opts['USER'], type = str)
+parser.add_argument("--ssh-loc-port", help = "Local port to use for forwarding", default = ssh.opts['LOC_PORT'], type = int)
+parser.add_argument("--ssh-port", help = "SSH port", default = ssh.opts['PORT'], type = int)
+parser.add_argument("--ssh-log", help = "Logfile for service log", default = ssh.opts['LOG'], type = str)
+parser.add_argument("--ssh-phs-exec", help = "Path to p.haul-service executable on the remote machine", default = ssh.opts['PHS_EXEC'], type = str)
+
 args = vars(parser.parse_args())
 
+# SSH module needs to fix args, so p.haul will connect to ssh tunnel
+args = ssh.parse_args(args)
+ssh.start()
+
 ph_type = (args.pop("type"), args.pop("id"))
 dst = (args.pop("to"), args.pop("port"))
 
diff --git a/p.haul-ssh b/p.haul-ssh
deleted file mode 100755
index 20b7912..0000000
--- a/p.haul-ssh
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/bash
-
-set -e
-
-# This script is a p.haul wrapper that allows to migrate process
-# using ssh tunnel for transferring data and without having to
-# start p.haul-service in advance.
-#
-# This script performs folowing actions:
-# 1) Launch p.haul-service on the remote and bind it to localhost:REM_PORT
-# 2) Parse cmdline options to extract ssh* opts and change
-#    p.haul opts appropriately, so p.haul will connect to
-#    localhost:LOC_PORT, that will be followed to the remote
-#    through the ssh tunnel.
-# 3) Establish ssh tunnel localhost:LOC_PORT->SSH->localhost:REM_PORT.
-# 4) Launch p.haul to start migration.
-
-TUNNEL_FLAGS="-o ExitOnForwardFailure=yes -fN "
-SERVER_FLAGS="-ttfM "
-LOC_PORT=54321
-REM_PORT=12345
-PORT=22
-USER="$(whoami)"
-REMOTE=""
-LOG="/tmp/phs.log"
-
-PH_EXEC="p.haul"
-PH_OPTS=()
-
-PHS_EXEC="p.haul-service"
-PHS_OPTS=()
-
-usage=\
-"SSH wrapper for p.haul\n\
-Usage: p.haul-ssh [SSH_OPTIONS] [PHAUL_OPTIONS]
-\n\
-SSH options:\n\
-  --ssh-compression   Use compression in ssh tunnel\n\
-  --ssh-username      Remote username (current user by default)\n\
-  --ssh-loc-port      Local port to use for forwarding (${LOC_PORT} by default)\n\
-  --ssh-port          SSH port (${PORT} by default)\n\
-  --ssh-log           Logfile for service log\n\
-  --ssh-ph-exec       Path to p.haul executable\n\
-  --ssh-phs-exec      Path to p.haul-service executable on the remote machine\n\
-  --help              Print this messange\n\
-\n\
-See p.haul --help for PHAUL_OPTIONS\n"
-
-while [ "$1" != "" ]; do
-	case $1 in
-	"--ssh-compression")
-		SERVER_FLAGS="${SERVER_FLAGS} -C"
-		TUNNEL_FLAGS="${TUNNEL_FLAGS} -C"
-		;;
-	"--ssh-username")
-		shift
-		USER=$1
-		;;
-	"--ssh-loc-port")
-		shift
-		LOC_PORT=$1
-		;;
-	"--port")
-		# Extract --port option(if present).
-		# --port LOC_PORT is added below.
-		shift
-		REM_PORT=$1
-		;;
-	"--ssh-ph-exec")
-		shift
-		PH_EXEC=$1
-		;;
-	"--ssh-phs-exec")
-		shift
-		PHS_EXEC=$1
-		;;
-	"--ssh-port")
-		shift
-		PORT=$1
-		;;
-	"--ssh-log")
-		shift
-		LOG=$1
-		;;
-	"--help")
-		printf "${usage}"
-		exit 0
-		;;
-	*)
-		PH_OPTS+=($1)
-		;;
-	esac
-	shift
-done
-
-# Replace p.haul positional "to" option with 127.0.0.1.
-REMOTE=${PH_OPTS[2]}
-PH_OPTS[2]="127.0.0.1"
-
-# Tell p.haul to connect to the local port
-PH_OPTS+=("--port ${LOC_PORT}")
-
-# Tell p.haul-service to bind on localhost, so it is not directly accesible
-# from the outer web.
-PHS_OPTS+=("--bind-port ${REM_PORT}")
-PHS_OPTS+=("--bind-addr \"127.0.0.1\"")
-
-# Use ssh multiplexing to speedup establishing additional ssh sessions and
-# to get control over all of them.
-CTL_SK="~/ph_ssh_${USER}_${REMOTE}_${PORT}"
-SSH_BASE="ssh -p ${PORT} ${USER}@${REMOTE} -S ${CTL_SK}"
-
-# Trap EXIT to stop ssh connection(i.e. all ssh sessions) on both normal
-# and error(see "set -e" above) exits.
-trap '${SSH_BASE} -S ${CTL_SK} -O exit &> /dev/null' EXIT
-
-echo "Start p.haul-service"
-${SSH_BASE} ${SERVER_FLAGS} ${PHS_EXEC} ${PHS_OPTS[@]} &> ${LOG} < /dev/null
-echo "Done"
-
-echo "Checking that p.haul-service is started"
-${SSH_BASE} "while netstat -lnt | awk '\$4 ~ /:${REM_PORT}$/ {exit 1}'; do echo 'Waiting...'; sleep 1; done"
-
-echo "Start ssh tunnel"
-${SSH_BASE} ${TUNNEL_FLAGS} -L 127.0.0.1:${LOC_PORT}:127.0.0.1:${REM_PORT}
-echo "Done"
-
-echo "Launch p.haul"
-${PH_EXEC} ${PH_OPTS[@]}
-echo "Done"
diff --git a/ssh.py b/ssh.py
new file mode 100644
index 0000000..a5b85eb
--- /dev/null
+++ b/ssh.py
@@ -0,0 +1,88 @@
+import atexit
+import xem_rpc
+import getpass
+import os
+
+opts = {
+	'TUNNEL_FLAGS'	: "-o ExitOnForwardFailure=yes -fN ",
+	'SERVER_FLAGS'	: "-ttfM",
+	'LOC_PORT'	: 54321,
+	'REM_PORT'	: xem_rpc.rpc_port,
+	'PORT'		: 22,
+	'USER'		: getpass.getuser(),
+	'REMOTE'	: "",
+	'LOG'		: "/tmp/phs.log",
+	'PHS_EXEC'	: "p.haul-service",
+	'PHS_OPTS'	: "",
+	'SSH_BASE'	: "ssh -p {PORT} {USER}@{REMOTE} -S ~/ph_ssh_{USER}_{REMOTE}_{PORT}"
+}
+
+_no_ssh = False
+
+def parse_args(args):
+	no_ssh = args.pop('no_ssh')
+
+	if not args.pop('no_ssh_comp'):
+		opts['SERVER_FLAGS'] += " -C"
+		opts['TUNNEL_FLAGS'] += " -C"
+
+	opts['USER']		= args.pop('ssh_user')
+	opts['LOC_PORT']	= args.pop('ssh_loc_port')
+
+	if not _no_ssh:
+		# Extract --port option and replace it with LOC_PORT
+		opts['REM_PORT']	= args.pop('port')
+		args['port']		= opts['LOC_PORT']
+
+	opts['PHS_EXEC']	= args.pop('ssh_phs_exec')
+	opts['PORT']		= args.pop('ssh_port')
+	opts['LOG']		= args.pop('ssh_log')
+
+	if not _no_ssh:
+		# Extract "to" option and replace it with 127.0.0.1
+		opts['REMOTE']	= args.pop('to')
+		args['to']	= "127.0.0.1"
+
+	# Tell p.haul-service to bind on localhost, so it is not
+	# directly accessible from the outer web.
+	opts['PHS_OPTS']	= "--bind-port "+str(opts['REM_PORT'])
+	opts['PHS_OPTS']	+= " --bind-addr 127.0.0.1"
+
+	# Use ssh multiplexing to speedup establishing additional
+	# ssh sessions and to get control over all of them.
+	opts['SSH_BASE']	= opts['SSH_BASE'].format(**opts)
+
+	return args
+
+def start():
+	if _no_ssh:
+		return
+
+	print("Start p.haul-service")
+	cmd = "{SSH_BASE} {SERVER_FLAGS} {PHS_EXEC} {PHS_OPTS} &> {LOG} < /dev/null".format(**opts)
+	if os.system(cmd):
+		raise Exception("Can't start p.haul-service")
+	print("Done")
+
+	print("Checking that p.haul-service is started")
+	cmd = '{SSH_BASE} "while netstat -lnt | awk \'\$4 ~ /:{REM_PORT}$/ {{exit 1}}\'; do echo \'Waiting...\'; sleep 1; done"'.format(**opts)
+	if os.system(cmd):
+		raise Exception("Can't check that p.haul-service is started")
+
+	print("Start ssh tunnel")
+	cmd = "{SSH_BASE} {TUNNEL_FLAGS} -L 127.0.0.1:{LOC_PORT}:127.0.0.1:{REM_PORT}".format(**opts)
+	if os.system(cmd):
+		raise Exception("Can't start ssh tunnel")
+	print("Done")
+
+	print("Launch p.haul")
+
+def stop():
+	if _no_ssh:
+		return
+
+	print("Stop SSH")
+	cmd = "{SSH_BASE} -O exit &> /dev/null".format(**opts)
+	os.system(cmd)
+
+atexit.register(stop)
-- 
2.1.0



More information about the CRIU mailing list