synnefo.
It comes in 2 variants:
- * snf-image-creator: A non-interactive command line program
- * snf-mkimage: A user-friendly dialog-based program
+ * snf-image-creator: A user-friendly dialog-based program
+ * snf-mkimage: A non-interactive command line program
#!/bin/sh
set -e
-PACKAGES_DIR=$1
+PACKAGES_DIR="$1"
shift
-TEMP_DIR=$(mktemp -d /tmp/devflow_autopkg_XXXXXXX)
+TEMP_DIR="$(mktemp -d /tmp/devflow_autopkg_XXXXXXX)"
# Create the packages
-devflow-autopkg snapshot -b $TEMP_DIR $@
+devflow-autopkg snapshot -b "$TEMP_DIR" "$@"
# MOVE the packages
-mkdir -p $PACKAGES_DIR
-mv -n $TEMP_DIR/* $PACKAGES_DIR
+mkdir -p "$PACKAGES_DIR"
+mv -n "$TEMP_DIR"/* "$PACKAGES_DIR"
echo "Moved packages to: $(pwd)/$PACKAGES_DIR"
#!/bin/sh
set -e
-DOCS_DIR=$1
+DOCS_DIR="$1"
cd docs
make html
cd -
-mkdir -p $DOCS_DIR
-mv -n docs/_build/html/* $DOCS_DIR
+mkdir -p "$DOCS_DIR"
+mv -n docs/_build/html/* "$DOCS_DIR"
echo "Moved docs to to: $(pwd)/$DOCS_DIR"
# (source start file, name, description, authors, manual section).
man_pages = [
('man/snf-image-creator', 'snf-image-creator',
- 'Command line image creator for Synnefo',
+ 'Dialog-based image creator for Synnefo',
'Synnefo development team <synnefo-devel@googlegroups.com>', 1),
('man/snf-mkimage', 'snf-mkimage',
- 'Dialog-based image creator for Synnefo',
+ 'Command line image creator for Synnefo',
'Synnefo development team <synnefo-devel@googlegroups.com>', 1)
]
Synopsis
--------
-**snf-image-creator** [OPTION] <INPUT MEDIA>
+**snf-image-creator** [OPTION] [<INPUT MEDIA>]
Description
-----------
Create image out of an <INPUT MEDIA>. The <INPUT MEDIA> may be a block device,
a regular file that represents a hard disk or \`/' to bundle the host system
-itself.
+itself. If the <INPUT MEDIA> argument is missing, the user will be asked during
+the program initializaton to specify one.
Options
-------
--a URL, --authentication-url=URL
- use this authentication URL when uploading/registering images
-
--c CLOUD, --cloud=CLOUD
- use this saved cloud account to authenticate against a cloud when
- uploading/registering images
-
---disable-sysprep=SYSPREP
- prevent SYSPREP operation from running on the input media
-
---enable-sysprep=SYSPREP
- run SYSPREP operation on the input media
-
--f, --force
- overwrite output files if they exist
-
+--version
+ show program's version number and exit
-h, --help
show this help message and exit
-
--m KEY=VALUE, --metadata=KEY=VALUE
- add custom KEY=VALUE metadata to the image
-
---no-shrink
- don't shrink any partition
-
---no-sysprep
- don't perform any system preparation operation
-
--o FILE, --outfile=FILE
- dump image to FILE
-
---public
- register image with the storage service as public
-
---print-sysprep
- print the enabled and disabled system preparation operations for this
- input media
-
--r IMAGENAME, --register=IMAGENAME
- register the image with the compute service with name IMAGENAME
-
--s, --silent
- output only errors
-
--t TOKEN, --token=TOKEN
- use this token when uploading/registering images
-
+-l FILE, --logfile=FILE
+ log all messages to FILE
--tmpdir=DIR
create large temporary image files under DIR
-
--u FILENAME, --upload=FILENAME
- save the image to the storage service with remote name FILENAME
-
---version
- show program's version number and exit
-
Synopsis
--------
-**snf-mkimage** [OPTION] [<INPUT MEDIA>]
+**snf-mkimage** [OPTION] <INPUT MEDIA>
Description
-----------
Create image out of an <INPUT MEDIA>. The <INPUT MEDIA> may be a block device,
a regular file that represents a hard disk or \`/' to bundle the host system
-itself. If the <INPUT MEDIA> argument is missing, the user will be asked during
-the program initializaton to specify one.
+itself.
Options
-------
---version
- show program's version number and exit
+-a URL, --authentication-url=URL
+ use this authentication URL when uploading/registering images
+
+--allow-unsupported
+ Proceed with the image creation even if the media is not supported
+
+-c CLOUD, --cloud=CLOUD
+ use this saved cloud account to authenticate against a cloud when
+ uploading/registering images
+
+--disable-sysprep=SYSPREP
+ prevent SYSPREP operation from running on the input media
+
+--enable-sysprep=SYSPREP
+ run SYSPREP operation on the input media
+
+-f, --force
+ overwrite output files if they exist
+
-h, --help
show this help message and exit
--l FILE, --logfile=FILE
- log all messages to FILE
+
+-m KEY=VALUE, --metadata=KEY=VALUE
+ add custom KEY=VALUE metadata to the image
+
+--no-shrink
+ don't shrink any partition
+
+--no-sysprep
+ don't perform any system preparation operation
+
+-o FILE, --outfile=FILE
+ dump image to FILE
+
+--public
+ register image with the storage service as public
+
+--print-syspreps
+ print the enabled and disabled system preparation operations for this
+ input media
+
+--print-sysprep-params
+ print the needed sysprep parameters for this input media
+
+-r IMAGENAME, --register=IMAGENAME
+ register the image with the compute service with name IMAGENAME
+
+-s, --silent
+ output only errors
+
+--sysprep-param=SYSPREP_PARAMS
+ add KEY=VALUE system preparation parameter
+
+-t TOKEN, --token=TOKEN
+ use this token when uploading/registering images
+
--tmpdir=DIR
create large temporary image files under DIR
+
+-u FILENAME, --upload=FILENAME
+ save the image to the storage service with remote name FILENAME
+
+--version
+ show program's version number and exit
+
snf-image-creator comes in 2 variants:
- * snf-image-creator: A non-interactive command line program
- * snf-mkimage: A user-friendly dialog-based program
+ * snf-mkimage: A non-interactive command line program
+ * snf-image-creator: A user-friendly dialog-based program
Both expect the input media as first argument. The input media may be a local
file, a block device or *"/"* if you want to create an image out of the running
Non-interactive version
=======================
-snf-image-creator receives the following options:
+snf-mkimage receives the following options:
.. code-block:: console
- $ snf-image-creator --help
- Usage: snf-image-creator [options] <input_media>
+ $ snf-mkimage --help
+ Usage: snf-mkimage [options] <input_media>
Options:
--version show program's version number and exit
VM's out of it. If you want the image to be visible by other user too, use the
*--public* option.
-By default, before extracting the image, snf-image-creator will perform a
+By default, before extracting the image, snf-mkimage will perform a
number of system preparation operations on the snapshot of the media and will
shrink the last partition found. Both actions can be disabled by specifying
*--no-sysprep* and *--no-shrink* respectively.
*-{enable,disable}-sysprep* options. The user may specify those options
multiple times.
-Running *snf-image-creator* with *--print-sysprep* on a raw file that hosts a
+Running *snf-mkimage* with *--print-sysprep* on a raw file that hosts a
debian system, we print the following output:
.. _sysprep:
.. code-block:: console
- $ snf-image-creator --print-sysprep ubuntu.raw
- snf-image-creator 0.3
+ $ snf-mkimage --print-syspreps ubuntu.raw
+ snf-image-creator 0.6
=====================
Examining source media `ubuntu_hd.raw' ... looks like an image file
Snapshotting media source ... done
.. code-block:: console
- $ snf-image-creator --enable-sysprep cleanup-mail --enable-sysprep remove-user-accounts ...
+ $ snf-mkimage --enable-sysprep cleanup-mail --enable-sysprep remove-user-accounts ...
Dialog-based version
====================
-*snf-mkimage* receives the following options:
+*snf-image-creator* receives the following options:
.. code-block:: console
- $ snf-mkimage --help
- Usage: snf-mkimage [options] [<input_media>]
+ $ snf-image-creator --help
+ Usage: snf-image-creator [options] [<input_media>]
Options:
--version show program's version number and exit
`Host bundling operation`_).
After the input media is examined and the program is initialized, the user will
-be given the choice to run *snf-mkimage* in *wizard* or *expert* mode.
+be given the choice to run *snf-image-creator* in *wizard* or *expert* mode.
Wizard mode
-----------
-When *snf-mkimage* runs in *wizard* mode, the user is just asked to provide the
+When *snf-image-creator* runs in *wizard* mode, the user is just asked to provide the
following basic information:
* Cloud: The cloud account to use to upload and register the resulting image
$ sudo kvm -m 1G -boot c -drive file=ubuntu.raw,format=raw,cache=none,if=virtio
-After you're done, you may use *snf-mkimage* as root to create and upload the
+After you're done, you may use *snf-image-creator* as root to create and upload the
image:
.. code-block:: console
$ sudo -s
- $ snf-mkimage ubuntu.raw
+ $ snf-image-creator ubuntu.raw
In the first screen you will be asked to choose if you want to run the program
in *Wizard* or *Expert* mode. Choose *Wizard*.
"image": image,
"metadata": metadata}
+ if image.is_unsupported():
+
+ session['excluded_tasks'] = [-1]
+ session['task_metadata'] = ["EXCLUDE_ALL_TASKS"]
+
+ msg = "The system on the input media is not supported." \
+ "\n\nReason: %s\n\n" \
+ "We highly recommend not to create an image out of this, " \
+ "since the image won't be cleaned up and you will not be " \
+ "able to configure it during the deployment. Press <YES> if " \
+ "you still want to continue with the image creation process." \
+ % image._unsupported
+
+ if not d.yesno(msg, width=WIDTH, defaultno=1, height=12):
+ main_menu(session)
+
+ d.infobox("Thank you for using snf-image-creator. Bye", width=53)
+ return 0
+
msg = "snf-image-creator detected a %s system on the input media. " \
"Would you like to run a wizard to assist you through the " \
"image creation process?\n\nChoose <Wizard> to run the wizard," \
"register it", width=SMALL_WIDTH)
return False
+ name = ""
+ description = session['metadata']['DESCRIPTION'] if 'DESCRIPTION' in \
+ session['metadata'] else ""
+
while 1:
- (code, answer) = d.inputbox("Please provide a registration name:",
- width=WIDTH)
+ fields = [
+ ("Registration name:", name, 60),
+ ("Description (optional):", description, 80)]
+
+ (code, output) = d.form(
+ "Please provide the following registration info:", height=11,
+ width=WIDTH, form_height=2, fields=fields)
+
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
return False
- name = answer.strip()
+ name, description = output
+ name = name.strip()
+ description = description.strip()
+
if len(name) == 0:
d.msgbox("Registration name cannot be empty", width=SMALL_WIDTH)
continue
break
+ session['metadata']['DESCRIPTION'] = description
metadata = {}
metadata.update(session['metadata'])
if 'task_metadata' in session:
def exclude_tasks(session):
"""Exclude specific tasks from running during image deployment"""
d = session['dialog']
+ image = session['image']
+
+ if image.is_unsupported():
+ d.msgbox("Image deployment configuration is disabled for unsupported "
+ "images.", width=SMALL_WIDTH)
+ return False
index = 0
displayed_index = 1
self.out.output('Inspecting Operating System ...', False)
roots = self.g.inspect_os()
- if len(roots) == 0:
- raise FatalError("No operating system found")
- if len(roots) > 1:
- raise FatalError("Multiple operating systems found."
- "We only support images with one OS.")
+
+ if len(roots) == 0 or len(roots) > 1:
+ self.root = None
+ self.ostype = "unsupported"
+ self.distro = "unsupported"
+ self.guestfs_device = '/dev/sda'
+ self.size = self.g.blockdev_getsize64(self.guestfs_device)
+
+ if len(roots) > 1:
+ reason = "Multiple operating systems found on the media."
+ else:
+ reason = "Unable to detect any operating system on the media."
+
+ self.set_unsupported(reason)
+ return
+
self.root = roots[0]
- self.guestfs_device = self.g.part_to_dev(self.root)
+ self.meta['PARTITION_TABLE'] = self.g.part_get_parttype('/dev/sda')
+ self.guestfs_device = '/dev/sda' # self.g.part_to_dev(self.root)
self.size = self.g.blockdev_getsize64(self.guestfs_device)
- self.meta['PARTITION_TABLE'] = \
- self.g.part_get_parttype(self.guestfs_device)
self.ostype = self.g.inspect_get_type(self.root)
self.distro = self.g.inspect_get_distro(self.root)
'found a(n) %s system' %
self.ostype if self.distro == "unknown" else self.distro)
+ # Inspect the OS
+ self.os.inspect()
+
+ def set_unsupported(self, reason):
+ """Flag this image us ansupported"""
+
+ self._unsupported = reason
+ self.meta['UNSUPPORTED'] = reason
+ self.out.warn('Media is not supported. Reason: %s' % reason)
+
+ def is_unsupported(self):
+ """Returns if this image is unsupported"""
+ return hasattr(self, '_unsupported')
+
def enable_guestfs(self):
"""Enable the guestfs handler"""
self.out.output("Shrinking image (this may take a while) ...", False)
+ if self.is_unsupported():
+ self.out.warn("Shrinking is disabled for unsupported images")
+ return self.size
+
sector_size = self.g.blockdev_getss(self.guestfs_device)
last_part = None
import StringIO
import signal
import json
+import textwrap
def check_writable_dir(option, opt_str, value, parser):
help="register image with the cloud as public",
action="store_true")
+ parser.add_option("--allow-unsupported", dest="allow_unsupported",
+ help="Proceed with the image creation even if the media "
+ "is not supported", default=False, action="store_true")
+
parser.add_option("--tmpdir", dest="tmp", type="string", default=None,
help="create large temporary image files under DIR",
metavar="DIR")
image = disk.get_image(snapshot, sysprep_params=options.sysprep_params)
+ if image.is_unsupported() and not options.allow_unsupported:
+ raise FatalError(
+ "The media seems to be unsupported.\n\n" +
+ textwrap.fill("To create an image from an unsupported media, "
+ "you'll need to use the`--allow-unsupported' "
+ "command line option. Using this is highly "
+ "discouraged, since the resulting image will "
+ "not be cleared out of sensitive data and will "
+ "not get customized during the deployment."))
+
for sysprep in options.disabled_syspreps:
image.os.disable_sysprep(image.os.get_sysprep_by_name(sysprep))
size = options.shrink and image.shrink() or image.size
metadata.update(image.meta)
+ if image.is_unsupported():
+ metadata['EXCLUDE_ALL_TASKS'] = "yes"
+
# Add command line metadata to the collected ones...
metadata.update(options.metadata)
sys.exit(ret)
except FatalError as e:
colored = sys.stderr.isatty()
+ warning = \
+ "The name of the executable has changed. If you want to use the " \
+ "user-friendly dialog-based program try `snf-image-creator'"
+ SimpleOutput(colored).warn(warning)
SimpleOutput(colored).error(e)
sys.exit(1)
except RuntimeError:
self._scrub_support = False
+ def inspect(self):
+ """Inspect the media to check if it is supported"""
+
+ if self.image.is_unsupported():
+ return
+
+ self.out.output('Running OS inspection:')
+ try:
+ if not self.mount(readonly=True):
+ raise FatalError("Unable to mount the media read-only")
+ self._do_inspect()
+ finally:
+ self.umount()
+
+ self.out.output()
+
def collect_metadata(self):
"""Collect metadata about the OS"""
try:
return
for name, param in self.needed_sysprep_params.items():
- self.out.output("\t%s (%s): %s" %
+ self.out.output("\t%s [%s]: %s" %
(param.description, name,
self.sysprep_params[name] if name in
self.sysprep_params else "(none)"))
def do_sysprep(self):
"""Prepare system for image creation."""
+ self.out.output('Preparing system for image creation:')
+
+ if self.image.is_unsupported():
+ self.out.warn(
+ "System preparation is disabled for unsupported media")
+ return
+
try:
if not self.mount(readonly=False):
raise FatalError("Unable to mount the media read-write")
- self.out.output('Preparing system for image creation:')
-
enabled = [task for task in self.list_syspreps() if task.enabled]
size = len(enabled)
if has_ftype(f, ftype):
action(full_path)
+ def _do_inspect(self):
+ """helper method for inspect"""
+ pass
+
def _do_collect_metadata(self):
"""helper method for collect_metadata"""
- self.meta['ROOT_PARTITION'] = \
- "%d" % self.image.g.part_to_partnum(self.root)
+
+ try:
+ self.meta['ROOT_PARTITION'] = \
+ "%d" % self.image.g.part_to_partnum(self.root)
+ except RuntimeError:
+ self.out.warn("Unable to identify the partition number from root "
+ "partition: %s" % self.root)
+
self.meta['OSFAMILY'] = self.image.g.inspect_get_type(self.root)
self.meta['OS'] = self.image.g.inspect_get_distro(self.root)
if self.meta['OS'] == "unknown":
self.out.warn("No passworded users found!")
del self.meta['USERS']
+ def _do_inspect(self):
+ """Run various diagnostics to check if media is supported"""
+
+ self.out.output('Checking partition table type...', False)
+ ptype = self.image.g.part_get_parttype(self.image.guestfs_device)
+ if ptype != 'gpt':
+ self.out.warn("partition table type is: `%s'" % ptype)
+ self.image.set_unsupported(
+ 'On FreeBSD only GUID partition tables are supported')
+ else:
+ self.out.success(ptype)
+
def _get_passworded_users(self):
"""Returns a list of non-locked user accounts"""
users = []
self.image.g.write('/etc/shadow', "\n".join(shadow) + '\n')
+ # Remove backup file for /etc/shadow
+ self.image.g.rm_rf('/etc/shadow-')
+
@sysprep('Fixing acpid powerdown action')
def fix_acpid(self):
"""Replace acpid powerdown action scripts to immediately shutdown the
return orig, dev, mpoint
+ def _do_inspect(self):
+ """Run various diagnostics to check if media is supported"""
+
+ self.out.output(
+ 'Checking if the media contains logical volumes (LVM)...', False)
+
+ has_lvm = True if len(self.image.g.lvs()) else False
+
+ if has_lvm:
+ self.out.output()
+ self.image.set_unsupported('The media contains logical volumes')
+ else:
+ self.out.success('no')
+
def _do_collect_metadata(self):
"""Collect metadata about the OS"""
super(Linux, self)._do_collect_metadata()
--- /dev/null
+# -*- 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 hosts code to handle unknown OSs."""
+
+from image_creator.os_type import OSBase
+
+
+class Unsupported(OSBase):
+ """OS class for unsupported OSs"""
+ def __init__(self, image, **kargs):
+ super(Unsupported, self).__init__(image, **kargs)
+
+ def collect_metadata(self):
+ """Collect metadata about the OS"""
+ self.out.warn("Unable to collect metadata for unsupported media")
+
+ def _do_mount(self, readonly):
+ """Mount partitions in corrent order"""
+ self.out.warn('not supported on this media.')
+ return False
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
import string
import subprocess
import struct
+import re
# For more info see: http://technet.microsoft.com/en-us/library/jj612867.aspx
KMS_CLIENT_SETUP_KEYS = {
+ "Windows 8.1 Professional": "GCRJD-8NW9H-F2CDX-CCM8D-9D6T9",
+ "Windows 8.1 Professional N": "HMCNV-VVBFX-7HMBH-CTY9B-B4FXY",
+ "Windows 8.1 Enterprise": "MHF9N-XY6XB-WVXMC-BTDCT-MKKG7",
+ "Windows 8.1 Enterprise N": "TT4HM-HN7YT-62K67-RGRQJ-JFFXW",
+ "Windows Server 2012 R2 Server Standard": "D2N9P-3P6X9-2R39C-7RTCD-MDVJX",
+ "Windows Server 2012 R2 Datacenter": "W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9",
+ "Windows Server 2012 R2 Essentials": "KNC87-3J2TX-XB4WP-VCPJV-M4FWM",
"Windows 8 Professional": "NG4HW-VH26C-733KW-K6F98-J8CK4",
"Windows 8 Professional N": "XCVCF-2NXM9-723PB-MHCB7-2RYQQ",
"Windows 8 Enterprise": "32JNW-9KQ84-P47T8-D8GGY-CWCK7",
'boot_timeout', int, 300, "Boot Timeout (seconds)", _POSINT)
@add_sysprep_param(
'connection_retries', int, 5, "Connection Retries", _POSINT)
+ @add_sysprep_param(
+ 'smp', int, 1, "Number of CPUs for the helper VM", _POSINT)
+ @add_sysprep_param(
+ 'mem', int, 1024, "Virtual RAM size for the helper VM (MiB)", _POSINT)
@add_sysprep_param('password', str, None, 'Image Administrator Password')
def __init__(self, image, **kargs):
super(Windows, self).__init__(image, **kargs)
raise FatalError(
'For windows support libguestfs 1.16.11 or above is required')
+ # Check if winexe is installed
+ if not WinEXE.is_installed():
+ raise FatalError(
+ "For windows support `Winexe' needs to be installed")
+
device = self.image.g.part_to_dev(self.root)
self.last_part_num = self.image.g.part_list(device)[-1]['part_num']
self._guest_exec(
r"cmd /q /c for /f %l in ('wevtutil el') do wevtutil cl %l")
- @sysprep('Executing Sysprep on the image (may take more that 10 minutes)')
+ @sysprep('Executing Sysprep on the image (may take more that 10 min)')
def microsoft_sysprep(self):
"""Run the Microsoft System Preparation Tool. This will remove
system-specific data and will make the image ready to be deployed.
# The maximum number of reclaimable bytes is: xxxx MB
#
if line.find('reclaimable') >= 0:
- querymax = line.split(':')[1].split()[0].strip()
- assert querymax.isdigit(), \
- "Number of reclaimable bytes not a number"
+ answer = line.split(':')[1].strip()
+ m = re.search('(\d+) MB', answer)
+ if m:
+ querymax = m.group(1)
+ else:
+ FatalError(
+ "Unexpected output for `shrink querymax' command: %s" %
+ line)
if querymax is None:
FatalError("Error in shrinking! "
querymax -= 100
if querymax < 0:
- self.out.warn("Not enought available space to shrink the image!")
+ self.out.warn("Not enough available space to shrink the image!")
return
self.out.output("\tReclaiming %dMB ..." % querymax)
monitorfd, monitor = tempfile.mkstemp()
os.close(monitorfd)
vm = _VM(self.image.device, monitor, self.sysprep_params)
- self.out.success("started (console on vnc display: %d)." %
+ self.out.success("started (console on VNC display: %d)" %
vm.display)
self.out.output("Waiting for OS to boot ...", False)
args.extend(needed_args)
args.extend([
- '-smp', '1', '-m', '1024', '-drive',
- 'file=%s,format=raw,cache=unsafe,if=virtio' % self.disk,
+ '-smp', str(self.params['smp']), '-m', str(self.params['mem']),
+ '-drive', 'file=%s,format=raw,cache=unsafe,if=virtio' % self.disk,
'-netdev', 'type=user,hostfwd=tcp::445-:445,id=netdev0',
'-device', 'virtio-net-pci,mac=%s,netdev=netdev0' % random_mac(),
'-vnc', ':%d' % self.display, '-serial', 'file:%s' % self.serial,
self.msg += "%s%s" % (msg, nl)
# If output is long, only output the last lines that fit in the box
lines = self.msg.splitlines()
- h = self.height
+ # The height of the active region is 2 lines shorter that the height of
+ # the dialog
+ h = self.height - 2
display = self.msg if len(lines) <= h else "\n".join(lines[-h:])
self.d.infobox(display, title=self.title, height=self.height,
width=self.width)
-__version__ = "0.5.3"
+__version__ = "0.5.3next"
__version_vcs_info__ = {
- 'branch': 'hotfix-0.5.3',
- 'revid': 'dc0ecb2',
+ 'branch': 'develop',
+ 'revid': '2a62304',
'revno': 402}
__version_user_email__ = "skalkoto@grnet.gr"
__version_user_name__ = "Nikos Skalkotos"
import subprocess
import time
import signal
+import distutils
from image_creator.util import FatalError
class WinEXE:
"""Wrapper class for the winexe command"""
+ @staticmethod
+ def is_installed(program='winexe'):
+ return distutils.spawn.find_executable(program) is not None
+
def __init__(self, username, password, hostname, program='winexe'):
self._host = hostname
self._user = username
install_requires=['sh', 'ansicolors', 'progress>=1.0.2'],
entry_points={
'console_scripts': [
- 'snf-image-creator = image_creator.main:main',
- 'snf-mkimage = image_creator.dialog_main:main']
+ 'snf-mkimage = image_creator.main:main',
+ 'snf-image-creator = image_creator.dialog_main:main']
}
)
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :