1 # -*- coding: utf-8 -*-
3 # Copyright 2013 GRNET S.A. All rights reserved.
5 # Redistribution and use in source and binary forms, with or
6 # without modification, are permitted provided that the following
9 # 1. Redistributions of source code must retain the above
10 # copyright notice, this list of conditions and the following
13 # 2. Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials
16 # provided with the distribution.
18 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
31 # The views and conclusions contained in the software and
32 # documentation are those of the authors and should not be
33 # interpreted as representing official policies, either expressed
34 # or implied, of GRNET S.A.
36 """This module provides an interface for the WinEXE utility"""
43 from image_creator.util import FatalError
46 class WinexeTimeout(FatalError):
47 """Raised when a WinExE command times-out"""
52 """Wrapper class for the winexe command"""
55 def is_installed(program='winexe'):
56 return distutils.spawn.find_executable(program) is not None
58 def __init__(self, username, password, hostname, program='winexe'):
64 # -U USERNAME[%PASSWORD]
65 user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
66 self._opts = ['-U', user]
69 """Reset all winexe options"""
71 # -U USERNAME[%PASSWORD]
72 user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
73 self._opts = ['-U', user]
75 def runas(self, username, password):
76 """Run command as this user"""
77 self._opts.append('--runas=%s%%%s' % (username, password))
81 """Use SYSTEM account"""
82 self._opts.append('--system')
86 """Uninstall winexe service after remote execution"""
87 self._opts.append('--uninstall')
91 """Reinstall winexe service before remote execution"""
92 self._opts.append('--reinstall')
95 def debug(self, level):
97 self._opts.append('--debuglevel=%d' % level)
100 def debug_stderr(self):
101 """Send debug output to STDERR"""
102 self._opts.append('--debug-stderr')
104 def run(self, command, timeout=0):
105 """Run a command on a remote windows system"""
107 args = [self._prog] + self._opts + ["//%s" % self._host] + [command]
108 run = subprocess.Popen(args, stdout=subprocess.PIPE,
109 stderr=subprocess.PIPE)
111 def handler(signum, frame):
115 if run.returncode is None:
118 raise WinexeTimeout("Command: `%s' timed-out" % " ".join(args))
120 signal.signal(signal.SIGALRM, handler)
121 signal.alarm(timeout)
122 stdout, stderr = run.communicate()
126 return (stdout, stderr, rc)
128 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :