[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