From: Ian Jackson Date: Fri, 18 May 2007 15:56:45 +0000 (+0100) Subject: WIP userv service and print-execute-command X-Git-Tag: converted-from-bzr~46^2~21 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=218c6a2454392488e9073192ac56099977c233e1;p=autopkgtest.git WIP userv service and print-execute-command --- diff --git a/debian/changelog b/debian/changelog index dd69925..a602540 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,9 @@ autopkgtest (0.9.0~iwj) unstable; urgency=low * WIP userv service. + * WIP print-execute-command command for virtualisation servers. - -- + -- Ian Jackson Fri, 18 May 2007 16:56:44 +0100 autopkgtest (0.8.2feisty1~iwj) feisty-updates; urgency=low diff --git a/debian/rules b/debian/rules index 00145e0..e3e98f3 100755 --- a/debian/rules +++ b/debian/rules @@ -46,6 +46,8 @@ binary binary-indep: checkdir sharedir_lnfrom=/usr/share/$p/$x \ sharedir=$(topdir)/debian/$p-$x/usr/share/$p/$x \ etcdir=$(topdir)/debian/$p-$x/etc cfg_suffix='' + cd debian/$p-$x/etc/userv/rules.d && \ + mv -f adt-xenlvm-testbed adt-xenlvm-testbed:dist set -e; for f in $p $p-$x; do \ cat CREDITS debian/copyright.suffix \ diff --git a/doc/README.virtualisation-server b/doc/README.virtualisation-server index e01137e..d391d65 100644 --- a/doc/README.virtualisation-server +++ b/doc/README.virtualisation-server @@ -63,6 +63,11 @@ Protocol (with distinct s) may be advertised in which case more than one such user is available. + + print-execute-command + The 'print-execute-command' command is available, so that the + caller can execute multiple concurrent commands on the testbed + with asynchronous input and output, if desired. + * Command open @@ -91,6 +96,66 @@ Protocol advertised). State: Open to Closed. +* Command + print-execute-command + response + ok ,,... auxverb|shstring [ ...] + Prints a command that can be executed by the caller to run a command + on the testbed. Only available if the `print-execute-command' + capability is advertised. + + The command has the following properties (which are, for example, + satisfiable when the virt server uses `env' `ssh' or `dchroot'): + - The caller is expected to url-decode and each , + append the command to be run on the testbed, and call exec on the + results. + - If auxverb is advertised, the supplied additional arguments to + command will be interpreted as the command and arguments to be + run on the testbed (as env and nice interpret their arguments) + - If shstring is advertised, there should be one additional + argument which will be fed to sh -c on the testbed (this is the + way ssh interprets its arguments). + - The testbed program's stdin, stdout and stderr will be plumbed + through to the stdin, stdout and stderr passed to ; this + may involve fd passing, or indirection via pipes or sockets. The + testbed program may not assume that the descriptors it receives + are seekable even if the originals are. + - It is not defined whether other file descriptors, environment + variables, and process properties in general, are inherited by + the testbed command. + - may exit as soon as the testbed command does, or it may + wait until every copy of the stdout and stderr descriptors passed + to the testbed command have been closed on the testbed. + - 's exit status will be that of the testbed command if + the latter exits with a value from 0..125. If the testbed + command dies due to a signal, then either (i) will exit + with the signal number with 128 added, or (ii) will die + with the same signal (although it may fail to dump core even if + the testbed program did), or (iii) will fail. If + fails it will exit 126, 127, 254, or 255; of course + may die to a some signals other than because the + testbed program died with the same signal. + - The caller may run several of these at once, subject to + limitation of resources (eg, file descriptors, processes) + - The behaviour if a command is running when the testbed is closed + or reverted is not defined. However, if the testbed advertises + `revert' then after the testbed is closed or reverted any such + invocation will not have any further effect on the + testbed. + - Sending signals in an attempt to terminate it may not + terminate all of the relevant processes and may not have any + effect on the testbed. + - The behaviour if no testbed command is specified (ie, if + just the specified and s is passed to exec) is + not defined. + - Currently no s are defined; they work the same + way as capabilities in that unrecognised ones should be ignored + by the caller. + The response (ie, the ) is only valid between `open' and + the next subsequent `close', `revert' or `quit'. Using it at other + times has undefined behaviour. + + * Command execute ,,... \ [ ...] diff --git a/settings.make b/settings.make index 0ddf956..92fc08b 100644 --- a/settings.make +++ b/settings.make @@ -12,6 +12,8 @@ sharedir_lnfrom = $(share)/$(pkgname) etcdir = /etc etcconfdir = $(etcdir)/autopkgtest etcinitddir = $(etcdir)/init.d +etcuservdir = $(etcdir)/userv +uservsvcdir = $(etcuservdir)/services.d xenscripts = $(etcdir)/xen/scripts cfg_suffix = .dist diff --git a/virt-subproc/VirtSubproc.py b/virt-subproc/VirtSubproc.py index 9f16c4b..9b3c36f 100644 --- a/virt-subproc/VirtSubproc.py +++ b/virt-subproc/VirtSubproc.py @@ -65,7 +65,8 @@ def cmdnumargs(c, ce, nargs=0, noptargs=0): def cmd_capabilities(c, ce): cmdnumargs(c, ce) - return caller.hook_capabilities() + ['execute-debug'] + return caller.hook_capabilities() + ['execute-debug', + 'print-execute-command'] def cmd_quit(c, ce): cmdnumargs(c, ce) @@ -76,6 +77,16 @@ def cmd_close(c, ce): if not downtmp: bomb("`close' when not open") cleanup() +def cmd_print_execute_command(c, ce): + cmdnumargs(c, ce) + if not downtmp: bomb("`print-execute-command' when not open") + if hasattr(caller,'hook_callerexeccmd'): + (cl,kvl) = caller.hook_callerexeccmd() + else + cl = down + kvl = ['auxverb'] + return ','.join(map(urllib.quote, cl)) + kvl + def preexecfn(): caller.hook_forked_inchild() @@ -315,7 +326,8 @@ def command(): c = map(urllib.unquote, ce) if not c: bomb('empty commands are not permitted') debug('executing '+string.join(ce)) - try: f = globals()['cmd_'+c[0]] + c_lookup = c[0].replace('-','_') + try: f = globals()['cmd_'+c_lookup] except KeyError: bomb("unknown command `%s'" % ce[0]) try: r = f(c, ce) diff --git a/virt-subproc/adt-virt-xenlvm b/virt-subproc/adt-virt-xenlvm index dc9795d..46ee14e 100755 --- a/virt-subproc/adt-virt-xenlvm +++ b/virt-subproc/adt-virt-xenlvm @@ -57,32 +57,60 @@ def check_pause(kind): os.kill(0, signal.SIGSTOP) def parse_args(): - global debuglevel, xlargs, gain_root, console, pauses + global debuglevel, with_testbed, console, pauses usage = "%prog [-- ]" parser = OptionParser(usage=usage) pa = parser.add_option pe = parser.error - pa('-r', '--gain-root', type='string', dest='gain_root'); - pa('-d', '--debug', action='store_true', dest='debug'); - pa('','--pause', type='string', dest='pause', default=''); + pa('-r', '--gain-root', type='string', dest='gain_root') + pa('-d', '--debug', action='store_true', dest='debug') + pa('', '--userv', action='store_true', dest='userv') + pa('', '--distro', type='string', dest='distro') + pa('', '--nominum', type='string', dest='nominum') + pa('','--pause', type='string', dest='pause', default='') (opts,xlargs) = parser.parse_args() vsp.debuglevel = opts.debug - - if opts.gain_root is None: gain_root = [] - else: gain_root = opts.gain_root.split() - vsp.down = gain_root + ['adt-xenlvm-on-testbed'] + xlargs + ['--'] - + xargs_userv = [] + xargs_direct = [] + + for k in ['distro','nominum']: + v = getattr(opts,k) + if v is None: continue + xargs_direct.append('--%s=%s' % (k, v)) + xargs_userv.append('-D%s=%s' % (k, v)) + + if not opts.userv: + if opts.gain_root is None: gain_root = [] + else: gain_root = opts.gain_root.split() + with_testbed = gain_root + ['adt-xenlvm-with-testbed'] + + xargs_direct + xlargs + + ['--','sh','-ec','echo y; exec cat'] + vsp.down = gain_root + ['adt-xenlvm-on-testbed'] + + xargs_direct + xlargs + ['--'] + else: + if opts.gain_root: + pe('--userv and --gain-root are not compatible') + basis = ['userv'] + xargs_userv + xlargs + + ['root','adt-xenlvm-testbed'] + get_down = subprocess.Popen(basis + ['pon0'], + stdin=file('/dev/null'), stdout=subprocess.PIPE, + stderr=None) + (pon0, _) = get_down.communicate() + if get_down.returncode: + vsp.bomb('failed to check userv service provision' + ' and subcommand details (code=%d) % + get_down.returncode) + vsp.down = pon0.split('\0') pauses = opts.pause.split(',') def do_open(): global withholder assert(withholder is None) withholder = subprocess.Popen( - gain_root + ['adt-xenlvm-with-testbed'] + xlargs + - ['--','sh','-ec','echo y; exec cat'], + with_testbed, stdin=subprocess.PIPE, stdout=subprocess.PIPE ) l = withholder.stdout.readline(2) rc = withholder.poll() diff --git a/virt-subproc/adt-virt-xenlvm.1 b/virt-subproc/adt-virt-xenlvm.1 index c831048..396d4b1 100644 --- a/virt-subproc/adt-virt-xenlvm.1 +++ b/virt-subproc/adt-virt-xenlvm.1 @@ -35,8 +35,19 @@ do any locking; it is the the caller's responsibility not to attempt concurrent use of any particular testbed. .SH OPTIONS .TP -.BR \-d " | " \-\-debug -Enables debugging output. Probably not hugely interesting. +.BI --distro= distro +Specifies a different distro (ie, the use of a different testbed). +.TP +.BI --nominum= nominum +Specifies a different nominum (ie, the use of a different testbed). +.TP +.BR \-\-userv +Specifies that the adt-xenlvm tools should not be run directly, but +rather via userv. The calling user must be permitted to use +.BR "userv root adt-xenlvm-testbed" . +In the default configuration, this means being a member of the +.B AdtXenUs +group. .TP .BI "-- --" adt-xenlvm-option = adt-xenlvm-value Following the first occurrence of @@ -44,12 +55,25 @@ Following the first occurrence of on the .B adt-virt-xenlvm commandline, any of the values in the adt-xenlvm configuration may be -set in the usual way. In particular, -.BI --nominum= nominum -can be used to specify the use of a different testbed. +set in the usual way. The arguments are simply passed to +\fBadt-virt-xenlvm\fR. See \fB/usr/share/doc/autopkgtest-xenlvm/README.gz\fR for full details of adt-xenlvm. +.TP +.BI "-- -D" varname = value +If \fB\-\-userv\fR was specified, options following the first +.B -- +on the +.B adt-virt-xenlvm +commandline are passed as option arguments to \fBuserv\fR. These +should normally be user-defined variable settings using \fB-D\fR which +are expected by the \fBautopkgtest-xenlvm/userv-target\fR script. +Currently only \fBdistro\fR and \fBnominum\fR are expected, and these +can be set using \fBadt-virt-xenlvm\fR's own options. +.TP +.BR \-d " | " \-\-debug +Enables debugging output. Probably not hugely interesting. .SH INPUT, OUTPUT AND EXIT STATUS The behaviour of .B adt-virt-xenlvm diff --git a/xen/Makefile b/xen/Makefile index 200e031..853db49 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -23,7 +23,7 @@ include ../settings.make programs = cleanup setup on-testbed with-testbed purge -shareprograms = fixups fixups-inside +shareprograms = fixups fixups-inside userv-target sharefiles = readconfig justconfig exec_prefix = adt-xenlvm- @@ -44,6 +44,8 @@ install: all set -e; for f in $(sharefiles); do \ $(INSTALL_DATA) $$f $(sharedir); \ done + $(INSTALL_DATA) userv-fragment \ + $(uservsvcdir)/adt-xenlvm-testbed:dist $(INSTALL_DATA) initscript $(etcinitddir)/adtxenlvm$(cfg_suffix) $(INSTALL_PROGRAM) vif-route-adt \ $(xenscripts)/vif-route-adt$(cfg_suffix) diff --git a/xen/on-testbed b/xen/on-testbed index 74f94da..60eabd5 100755 --- a/xen/on-testbed +++ b/xen/on-testbed @@ -3,4 +3,13 @@ set -e . ${ADT_XENLVM_SHARE:=/usr/share/autopkgtest/xenlvm}/justconfig while test $# -gt $nonoptargs; do shift; done -ssh $adt_ssh_keyident_args $adt_guest_ipaddr "$@" +case "$1" in +x--print-command) ppfx=echo; shift ;; +x--print0-command) ppfx=ppfx0; shift ;; +x--) shift ;; +x-*) fail "invalid instead-of-command options \`$1'" ;; +esac + +ppfx0 () { for x in "$@"; do printf '%s\0' "$x"; done; } + +$ppfx ssh $adt_ssh_keyident_args $adt_guest_ipaddr "$@" diff --git a/xen/userv-fragment b/xen/userv-fragment index ad0dd41..d18dd9f 100644 --- a/xen/userv-fragment +++ b/xen/userv-fragment @@ -4,5 +4,6 @@ if ( glob calling-group AdtXenUs root reset no-set-environment no-disconnect-hup + no-suppress-args execute /usr/share/autopkgtest/xenlvm/userv-target fi diff --git a/xen/userv-target b/xen/userv-target index e9ad631..1b874f3 100755 --- a/xen/userv-target +++ b/xen/userv-target @@ -1,8 +1,27 @@ #!/bin/bash set -e -d="$USERV_U_distro" fail () { printf >&2 "%s: %s\n" "$0" "$*"; exit 127; } -test "x$d" = "x${d#/*}" || fail 'distro may not contain slashes' -test -d /var/lib/autopkgtest/xenlvm/adt_"$d" || fail 'unknown distro' -exec adt-xenlvm-with-testbed --adt-distro="$d" sh -c 'echo y && exec cat' +. /etc/lsb-release + +d="${USERV_U_distro-$DISTRIB_CODENAME}" +n="${USERV_U_nominum-adt}" + +case "$dn" in +*/*|.*|*.*|*_*_*) fail 'dangerous format in distro or nominum' ;; +adt*) ;; +*) fail 'userv adtxenlvm only supports nominums starting with adt' ;; +esac + +test -d /var/lib/autopkgtest/xenlvm/"$dn" || fail 'unknown distro or nominum' + +run () { + base="$1"; shift + exec "$base" --adt-distro="$d" --adt-nominum="$n" "$@" +} + +case "$1" in +with) run adt-xenlvm-with-testbed sh -c 'echo y && exec cat' ;; +pon0) run adt-xenlvm-on-testbed -- --print0-command ;; +*) fail 'unknown mode' +esac