Simone Tiraboschi has uploaded a new change for review. Change subject: packaging: setup: auto-detect available appliance images and suggest them ......................................................................
packaging: setup: auto-detect available appliance images and suggest them Autodetects available appliance images Suggest them if no one is available Validate the sha1sum of the selected appliance Makes the appliance flow the default one https://bugzilla.redhat.com/1211532 Change-Id: Iaddd10521e71d5c855473817a563c8c1c6a1b0a8 Signed-off-by: Simone Tiraboschi <stira...@redhat.com> --- M src/ovirt_hosted_engine_setup/constants.py M src/plugins/ovirt-hosted-engine-setup/vm/boot_disk.py M src/plugins/ovirt-hosted-engine-setup/vm/configurevm.py 3 files changed, 146 insertions(+), 19 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-hosted-engine-setup refs/changes/87/41987/1 diff --git a/src/ovirt_hosted_engine_setup/constants.py b/src/ovirt_hosted_engine_setup/constants.py index c21882a..091afb9 100644 --- a/src/ovirt_hosted_engine_setup/constants.py +++ b/src/ovirt_hosted_engine_setup/constants.py @@ -151,6 +151,11 @@ 'glusterfs', 'glusterd.vol' ) + OVIRT_APPLIANCES_DESC_DIR = os.path.join( + config.SYSCONFDIR, + OVIRT_HOSTED_ENGINE, + ) + OVIRT_APPLIANCES_DESC_FILENAME_TEMPLATE = '*-appliance.conf' OVIRT_HOSTED_ENGINE_TEMPLATE = os.path.join( config.DATADIR, OVIRT_HOSTED_ENGINE_SETUP, @@ -945,7 +950,7 @@ DEFAULT_IMAGE_DESC = 'Hosted Engine Image' DEFAULT_IMAGE_SIZE_GB = 25 # based on minimum requirements. DEFAULT_MEM_SIZE_MB = 4096 # based on minimum requirements. - DEFAULT_BOOT = 'cdrom' # boot device - drive C or cdrom or pxe + DEFAULT_BOOT = 'disk' # boot device - drive C or cdrom or pxe DEFAULT_CDROM = '/dev/null' DEFAULT_BRIDGE_IF = 'em1' DEFAULT_BRIDGE_NAME = 'ovirtmgmt' diff --git a/src/plugins/ovirt-hosted-engine-setup/vm/boot_disk.py b/src/plugins/ovirt-hosted-engine-setup/vm/boot_disk.py index c3dbd8f..ca81549 100644 --- a/src/plugins/ovirt-hosted-engine-setup/vm/boot_disk.py +++ b/src/plugins/ovirt-hosted-engine-setup/vm/boot_disk.py @@ -23,8 +23,11 @@ """ +import configparser import gettext import glob +import hashlib +from io import StringIO import json import os import shutil @@ -223,6 +226,63 @@ self._image_path = None self._ovf_mem_size_mb = None + def _detect_appliances(self): + self.logger.info(_('Detecting available oVirt engine appliances')) + appliances = [] + config = configparser.ConfigParser() + config.optionxform = str + confdir = os.path.join( + ohostedcons.FileLocations.OVIRT_APPLIANCES_DESC_DIR, + ohostedcons.FileLocations.OVIRT_APPLIANCES_DESC_FILENAME_TEMPLATE, + ) + conffiles = glob.glob(confdir) + fakesection = 'appliance' + keys = ['description', 'version', 'path', 'sha1sum'] + for cf in conffiles: + self.logger.debug('parsing: ' + cf) + with open(cf) as stream: + fakefile = StringIO( + u'[{s}]\n'.format(s=fakesection) + stream.read() + ) + config.readfp(fakefile) + if set( + [config.has_option(fakesection, k) for k in keys] + ) == set([True]): + app = {k: self.config.get(fakesection, k) + for k in keys + } + app.update( + {'index': str(len(appliances)+1)} + ) + appliances.append(app) + else: + self.logger.error('error parsing: ' + cf) + self.logger.debug('available appliances: ' + str(self._appliances)) + if not appliances: + self.logger.info( + 'No engine appliance image is available on your system\n' + 'Using an oVirt engine appliance could greatly speed-up ' + 'ovirt hosted-engine deploy\n' + 'You could get oVirt engine appliance installing ' + 'ovirt-engine-appliance rpm' + ) + return appliances + + def _file_hash(self, filename): + h = hashlib.sha1() + with open(filename, 'rb') as file: + chunk = 0 + while chunk != b'': + chunk = file.read(1024) + h.update(chunk) + self.logger.debug( + "calculated sha1sum for {f}: {g}".format( + f=filename, + h=h.hexdigest(), + ) + ) + return h.hexdigest() + def _parse_ovf(self, tar, ovf_xml): valid = True tmpdir = tempfile.mkdtemp() @@ -402,26 +462,86 @@ interactive = self.environment[ ohostedcons.VMEnv.OVF ] is None + appliances = [] + if interactive: + appliances = self._detect_appliances() + if appliances: + directlyOVA = str(len(appliances)+1) + app_list = '' + for entry in appliances: + app_list += _( + '\t[{i}] - {description} - {version}\n' + ).format( + i=entry['index'], + description=entry['description'], + version=entry['version'], + ) + app_list += ( + _('\t[{i}] - {Directly select an OVA file}\n').format( + i=directlyOVA, + description=_('Directly select an OVA file'), + ) + ) + valid = False while not valid: if interactive: - self.environment[ - ohostedcons.VMEnv.OVF - ] = self.dialog.queryString( - name='OVEHOSTED_VMENV_OVF', - note=_( - 'Please specify path to OVF archive ' - 'you would like to use [@DEFAULT@]: ' - ), - prompt=True, - caseSensitive=True, - default=str(self.environment[ - ohostedcons.VMEnv.OVF - ]), - ) + ova_path = '' + if appliances: + self.dialog.note( + _( + 'The following appliance have been ' + 'found on your system:\n' + '{app_list}' + ).format( + app_list=app_list, + ) + ) + sapp = self.dialog.queryString( + name='OVEHOSTED_STORAGE_BLOCKD_LUN', + note=_( + 'Please select the destination LUN ' + '(@VALUES@) [@DEFAULT@]: ' + ), + prompt=True, + caseSensitive=True, + default='1', + validValues=[str(i+1) for i in range(len(app_list))], + ) + if sapp != directlyOVA: + ova_path = appliances[int(sapp)-1]['path'] + if ( + self._file_hash(ova_path) != + appliances[int(sapp)-1]['sha1sum'] + ): + self.logger.error( + _( + "The selected appliance is invalid: the " + "sha1sum of the selected file ('{p}') " + "doesn't match the expected value." + ).format(p=ova_path) + ) + continue + if not ova_path: + ova_path = self.dialog.queryString( + name='OVEHOSTED_VMENV_OVF', + note=_( + 'Please specify path to OVF archive ' + 'you would like to use [@DEFAULT@]: ' + ), + prompt=True, + caseSensitive=True, + default=str(self.environment[ + ohostedcons.VMEnv.OVF + ]), + ) + else: # Not interactive + ova_path = self.environment[ohostedcons.VMEnv.OVF] - valid = self._check_ovf(self.environment[ohostedcons.VMEnv.OVF]) - if not valid: + valid = self._check_ovf(ova_path) + if valid: + self.environment[ohostedcons.VMEnv.OVF] = ova_path + else: if interactive: self.logger.error( _( diff --git a/src/plugins/ovirt-hosted-engine-setup/vm/configurevm.py b/src/plugins/ovirt-hosted-engine-setup/vm/configurevm.py index 74e9c0d..4a2185c 100644 --- a/src/plugins/ovirt-hosted-engine-setup/vm/configurevm.py +++ b/src/plugins/ovirt-hosted-engine-setup/vm/configurevm.py @@ -126,6 +126,7 @@ self.environment[ohostedcons.VMEnv.CDROM] = None self.environment[ohostedcons.VMEnv.OVF] = None else: + self._detect_appliances() interactive = self.environment[ ohostedcons.VMEnv.BOOT ] is None @@ -137,8 +138,9 @@ ] = self.dialog.queryString( name='OVEHOSTED_VMENV_BOOT', note=_( - 'Please specify the device to boot the VM ' - 'from (@VALUES@) [@DEFAULT@]: ' + 'Please specify the device to boot the VM from ' + '(choose disk for the oVirt engine appliance)\n' + '(@VALUES@) [@DEFAULT@]: ' ), prompt=True, caseSensitive=True, -- To view, visit https://gerrit.ovirt.org/41987 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaddd10521e71d5c855473817a563c8c1c6a1b0a8 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-hosted-engine-setup Gerrit-Branch: master Gerrit-Owner: Simone Tiraboschi <stira...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches