Statistics
| Branch: | Tag: | Revision:

root / image_creator / winexe.py @ 63af9c37

History | View | Annotate | Download (4 kB)

1
# -*- coding: utf-8 -*-
2
#
3
# Copyright 2013 GRNET S.A. All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or
6
# without modification, are permitted provided that the following
7
# conditions are met:
8
#
9
#   1. Redistributions of source code must retain the above
10
#      copyright notice, this list of conditions and the following
11
#      disclaimer.
12
#
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.
17
#
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.
30
#
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.
35

    
36
"""This module provides an interface for the WinEXE utility"""
37

    
38
import subprocess
39
import time
40
import signal
41

    
42
from image_creator.util import FatalError
43

    
44

    
45
class WinexeTimeout(FatalError):
46
    """Raised when a WinExE command times-out"""
47
    pass
48

    
49

    
50
class WinEXE:
51
    """Wrapper class for the winexe command"""
52

    
53
    def __init__(self, username, password, hostname, program='winexe'):
54
        self._host = hostname
55
        self._user = username
56
        self._pass = password
57
        self._prog = program
58

    
59
        # -U USERNAME[%PASSWORD]
60
        user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
61
        self._opts = ['-U', user]
62

    
63
    def reset(self):
64
        """Reset all winexe options"""
65

    
66
        # -U USERNAME[%PASSWORD]
67
        user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
68
        self._opts = ['-U', user]
69

    
70
    def runas(self, username, password):
71
        """Run command as this user"""
72
        self._opts.append('--runas=%s%%%s' % (username, password))
73
        return self
74

    
75
    def system(self):
76
        """Use SYSTEM account"""
77
        self._opts.append('--system')
78
        return self
79

    
80
    def uninstall(self):
81
        """Uninstall winexe service after remote execution"""
82
        self._opts.append('--uninstall')
83
        return self
84

    
85
    def reinstall(self):
86
        """Reinstall winexe service before remote execution"""
87
        self._opts.append('--reinstall')
88
        return self
89

    
90
    def debug(self, level):
91
        """Set debug level"""
92
        self._opts.append('--debuglevel=%d' % level)
93
        return self
94

    
95
    def debug_stderr(self):
96
        """Send debug output to STDERR"""
97
        self._opts.append('--debug-stderr')
98

    
99
    def run(self, command, timeout=0):
100
        """Run a command on a remote windows system"""
101

    
102
        args = [self._prog] + self._opts + ["//%s" % self._host] + [command]
103
        run = subprocess.Popen(args, stdout=subprocess.PIPE,
104
                               stderr=subprocess.PIPE)
105

    
106
        def handler(signum, frame):
107
            run.terminate()
108
            time.sleep(1)
109
            run.poll()
110
            if run.returncode is None:
111
                run.kill()
112
            run.wait()
113
            raise WinexeTimeout("Command: `%s' timed-out" % " ".join(args))
114

    
115
        signal.signal(signal.SIGALRM, handler)
116
        signal.alarm(timeout)
117
        stdout, stderr = run.communicate()
118
        rc = run.poll()
119
        signal.alarm(0)
120

    
121
        return (stdout, stderr, rc)
122

    
123
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :