Skip to content
Snippets Groups Projects
Commit f5873ed0 authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

Add a new winexe module

This contains a wrapper class for winexe utility
parent c53cc8dd
No related branches found
No related tags found
No related merge requests found
......@@ -38,6 +38,7 @@ Windows OSs."""
from image_creator.os_type import OSBase, sysprep
from image_creator.util import FatalError, check_guestfs_version, get_command
from image_creator.winexe import WinEXE, WinexeTimeout
import hivex
import tempfile
......@@ -685,15 +686,15 @@ class Windows(OSBase):
def _guest_exec(self, command, fatal=True):
"""Execute a command on a windows VM"""
user = "Administrator%" + self.sysprep_params['password']
addr = 'localhost'
runas = '--runas=%s' % user
winexe = subprocess.Popen(
['winexe', '-U', user, runas, "--uninstall", "//%s" % addr,
command], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
passwd = self.sysprep_params['password']
stdout, stderr = winexe.communicate()
rc = winexe.poll()
winexe = WinEXE('Administrator', passwd, 'localhost')
winexe.runas('Administrator', passwd).uninstall()
try:
(stdout, stderr, rc) = winexe.run(command)
except WinexeTimeout:
FatalError("Command: `%s' timeout out." % command)
if rc != 0 and fatal:
reason = stderr if len(stderr) else stdout
......
# -*- coding: utf-8 -*-
#
# Copyright 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
"""This module provides an interface for the WinEXE utility"""
import subprocess
import time
import signal
from image_creator.util import FatalError
class WinexeTimeout(FatalError):
"""Raised when a WinExE command times-out"""
pass
class WinEXE:
"""Wrapper class for the winexe command"""
def __init__(self, username, password, hostname, program='winexe'):
self._host = hostname
self._user = username
self._pass = password
self._prog = program
# -U USERNAME[%PASSWORD]
user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
self._opts = ['-U', user]
def reset(self):
"""Reset all winexe options"""
# -U USERNAME[%PASSWORD]
user = '%s%s' % (self._user, '%%%s' % self._pass if self._pass else "")
self._opts = ['-U', user]
def runas(self, username, password):
"""Run command as this user"""
self._opts.append('--runas=%s%%%s' % (username, password))
return self
def system(self):
"""Use SYSTEM account"""
self._opts.append('--system')
return self
def uninstall(self):
"""Uninstall winexe service after remote execution"""
self._opts.append('--uninstall')
return self
def reinstall(self):
"""Reinstall winexe service before remote execution"""
self._opts.append('--reinstall')
return self
def debug(self, level):
"""Set debug level"""
self._opts.append('--debuglevel=%d' % level)
return self
def debug_stderr(self):
"""Send debug output to STDERR"""
self._opts.append('--debug-stderr')
def run(self, command, timeout=0):
"""Run a command on a remote windows system"""
args = [self._prog] + self._opts + ["//%s" % self._host] + [command]
run = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
def handler(signum, frame):
run.terminate()
time.sleep(1)
run.poll()
if run.returncode is None:
run.kill()
run.wait()
raise WinexeTimeout("Command: `%s' timed-out" % " ".join(args))
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)
stdout, stderr = run.communicate()
rc = run.poll()
signal.alarm(0)
return (stdout, stderr, rc)
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment