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"""
42 from image_creator.util import FatalError
45 class WinexeTimeout(FatalError):
46 """Raised when a WinExE command times-out"""
51 """Wrapper class for the winexe command"""
53 def __init__(self, username, password, hostname, program='winexe'):
59 # -U USERNAME[%PASSWORD]
60 user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
61 self._opts = ['-U', user]
64 """Reset all winexe options"""
66 # -U USERNAME[%PASSWORD]
67 user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
68 self._opts = ['-U', user]
70 def runas(self, username, password):
71 """Run command as this user"""
72 self._opts.append('--runas=%s%%%s' % (username, password))
76 """Use SYSTEM account"""
77 self._opts.append('--system')
81 """Uninstall winexe service after remote execution"""
82 self._opts.append('--uninstall')
86 """Reinstall winexe service before remote execution"""
87 self._opts.append('--reinstall')
90 def debug(self, level):
92 self._opts.append('--debuglevel=%d' % level)
95 def debug_stderr(self):
96 """Send debug output to STDERR"""
97 self._opts.append('--debug-stderr')
99 def run(self, command, timeout=0):
100 """Run a command on a remote windows system"""
102 args = [self._prog] + self._opts + ["//%s" % self._host] + [command]
103 run = subprocess.Popen(args, stdout=subprocess.PIPE,
104 stderr=subprocess.PIPE)
106 def handler(signum, frame):
110 if run.returncode is None:
113 raise WinexeTimeout("Command: `%s' timed-out" % " ".join(args))
115 signal.signal(signal.SIGALRM, handler)
116 signal.alarm(timeout)
117 stdout, stderr = run.communicate()
121 return (stdout, stderr, rc)
123 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :