Sandro Bonazzola has uploaded a new change for review. Change subject: HC: provisioning replica 3 volume ......................................................................
HC: provisioning replica 3 volume Provision a Replica 3 Gluster volume instead of a single brick volume. Change-Id: I5fcde43354268477e4c8a92ee29470750da7337a Bug-Url: https://bugzilla.redhat.com/1217448 Signed-off-by: Sandro Bonazzola <sbona...@redhat.com> --- M src/ovirt_hosted_engine_setup/constants.py M src/plugins/ovirt-hosted-engine-setup/storage/glusterfs.py 2 files changed, 137 insertions(+), 36 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-hosted-engine-setup refs/changes/32/41332/1 diff --git a/src/ovirt_hosted_engine_setup/constants.py b/src/ovirt_hosted_engine_setup/constants.py index c6195d6..4245e36 100644 --- a/src/ovirt_hosted_engine_setup/constants.py +++ b/src/ovirt_hosted_engine_setup/constants.py @@ -550,10 +550,10 @@ @ohostedattrs( answerfile=True, summary=True, - description=_('GlusterFS Brick'), + description=_('GlusterFS Bricks'), ) - def GLUSTER_BRICK(self): - return 'OVEHOSTED_STORAGE/glusterBrick' + def GLUSTER_BRICKS(self): + return 'OVEHOSTED_STORAGE/glusterBricks' @ohostedattrs( answerfile=True, diff --git a/src/plugins/ovirt-hosted-engine-setup/storage/glusterfs.py b/src/plugins/ovirt-hosted-engine-setup/storage/glusterfs.py index 745993f..f9da948 100644 --- a/src/plugins/ovirt-hosted-engine-setup/storage/glusterfs.py +++ b/src/plugins/ovirt-hosted-engine-setup/storage/glusterfs.py @@ -23,7 +23,7 @@ """ import gettext -import socket +import time from otopi import constants as otopicons @@ -31,6 +31,7 @@ from otopi import plugin from otopi import transaction from otopi import util +from vdsm import netinfo from vdsm import vdscli @@ -48,9 +49,13 @@ GlusterFS storage provisioning plugin. """ + CONNECTION_MAX_COUNT = 10 + CONNECTION_WAIT = 2 + def __init__(self, context): super(Plugin, self).__init__(context=context) self._checker = ohosteddomains.DomainChecker() + self._local_ip_addresses = None def _configure_glusterfs_service(self): """ @@ -66,6 +71,8 @@ elif line.find('base-port') != -1: continue elif line.find('end-volume') == 0: + # TODO: remove rpc-auth-allow-insecure config after + # gluster3.7.1 is out and required. content.append(' option rpc-auth-allow-insecure on') content.append(' option base-port 49217') content.append(line) @@ -88,7 +95,9 @@ """ cli = vdscli.connect() share = self.environment[ohostedcons.StorageEnv.GLUSTER_SHARE_NAME] - brick = self.environment[ohostedcons.StorageEnv.GLUSTER_BRICK] + bricks = self.environment[ + ohostedcons.StorageEnv.GLUSTER_BRICKS + ].split(',') self.logger.debug('glusterVolumesList') response = cli.glusterVolumesList() self.logger.debug(response) @@ -98,8 +107,8 @@ volumes = response['volumes'] if share in volumes: self.logger.info(_('GlusterFS Volume already exists')) - if set([brick]) != set(volumes[share]['bricks']): - self.logger.debug(set([brick])) + if set([bricks]) != set(volumes[share]['bricks']): + self.logger.debug(set([bricks])) self.logger.debug(set(volumes[share]['bricks'])) raise RuntimeError( _( @@ -108,15 +117,62 @@ ) ) else: + self.logger.info(_('Adding hosts to the Gluster Pool')) + self.logger.debug(cli.glusterHostsList()) + for brick in bricks: + host = brick.split(':')[0] + if host not in self._local_ip_addresses: + self.logger.debug('glusterHostAdd("%s")' % host) + response = cli.glusterHostAdd(host) + self.logger.debug(response) + if response['status']['code'] != 0: + self.logger.error( + _( + 'Failed to add {host} to the Gluster Pool' + ).format(host=host) + ) + raise RuntimeError(response['status']['message']) + ready = False + count = 0 + while not ready: + count += 1 + response = cli.glusterHostsList() + self.logger.debug(response) + if response['status']['code'] != 0: + self.logger.error( + _('Failed to get the Gluster Pool status') + ) + raise RuntimeError(response['status']['message']) + wait_list = [] + for host in response['hosts']: + if host['status'] != 'CONNECTED': + wait_list.append(host['hostname']) + if wait_list: + self.logger.info( + _('Still waiting for {hosts} to be connected').format( + hosts=', '.join(wait_list) + ) + ) + if count < self.CONNECTION_MAX_COUNT: + time.sleep(self.CONNECTION_WAIT) + else: + raise RuntimeError( + _( + 'Timeout while waiting for hosts to be ' + 'connected' + ) + ) + else: + ready = True self.logger.info(_('Creating GlusterFS Volume')) - replica_count = '' + replica_count = '3' stripe_count = '' transport_list = ['tcp'] - force = True + force = True # Handle allowed but unsupported cases self.logger.debug('glusterVolumeCreate') response = cli.glusterVolumeCreate( share, - [brick], + bricks, replica_count, stripe_count, transport_list, @@ -204,7 +260,7 @@ ohostedcons.Defaults.DEFAULT_GLUSTER_SHARE_NAME ) self.environment.setdefault( - ohostedcons.StorageEnv.GLUSTER_BRICK, + ohostedcons.StorageEnv.GLUSTER_BRICKS, None ) @@ -234,9 +290,8 @@ ] = self.dialog.queryString( name='OVEHOSTED_GLUSTER_PROVISIONING', note=_( - 'Do you want to configure this host for ' - 'providing GlusterFS storage (will start with no replica ' - 'requires to grow to replica 3 later)? ' + 'Do you want to configure the system for ' + 'providing Replica 3 GlusterFS storage? ' '(@VALUES@)[@DEFAULT@]: ' ), prompt=True, @@ -259,33 +314,79 @@ ) def _brick_customization(self): interactive = self.environment[ - ohostedcons.StorageEnv.GLUSTER_BRICK + ohostedcons.StorageEnv.GLUSTER_BRICKS ] is None - if interactive: - path = self.dialog.queryString( - name='OVEHOSTED_GLUSTER_BRICKS', - note=_( - 'Please provide a path to be used for the brick ' - 'on this host:' - ), - prompt=True, - caseSensitive=True, - ) - self.environment[ - ohostedcons.StorageEnv.GLUSTER_BRICK - ] = '%s:%s' % (socket.gethostname(), path) - else: - host = self.environment[ - ohostedcons.StorageEnv.GLUSTER_BRICK - ].split(':')[0] - if host != socket.gethostname(): - raise ValueError( - _('The specified brick must be on this host') + user_input = self.environment[ohostedcons.StorageEnv.GLUSTER_BRICKS] + valid = False + hosts = set() + while not valid: + # Check that 3 bricks have been specified + # Check that each brick is host:/path + # Check that at least one brick is on local host + # Check that 3 different hosts are used + if interactive: + user_input = self.dialog.queryString( + name='OVEHOSTED_GLUSTER_BRICKS', + note=_( + 'Please provide a comma separated list of 3 bricks ' + 'using the IP address of the NIC to be used for ' + 'the storage. Ensure that Gluster Server daemon is ' + 'installed and running on the specified hosts before ' + 'continuing. ' + '(ip_addr1:/path1,ip_addr2:/path2,ip_addr3:/path3): ' + ), + prompt=True, + caseSensitive=True, ) + bricks = user_input.split(',') + try: + if len(bricks) != 3: + raise ValueError( + _('Only {bricks} have been specified').format( + bricks=bricks + ) + ) + for brick in bricks: + try: + host, _path = brick.split(':') + except ValueError: + raise ValueError( + _( + 'Invalid brick: {brick} has been specified' + ).format( + brick=brick + ) + ) + hosts.add(host) + self._local_ip_addresses = set([ + addr.split('/')[0] for addr in netinfo.getIpAddresses() + ]) + if not self._local_ip_addresses.intersection(hosts): + raise ValueError( + _('No local brick has been specified') + ) + if len(hosts) != 3: + self.logger.warning( + _( + 'Only {hosts} hosts have been specified. ' + 'Using less than three hosts for Replica 3 ' + 'deployment is allowed but not supported.' + ) + ) + valid = True + self.environment[ + ohostedcons.StorageEnv.GLUSTER_BRICKS + ] = user_input + except ValueError as e: + if interactive: + self.logger.error(str(e)) + continue + else: + raise e self.environment[ ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION ] = '{host}:/{share}'.format( - host=socket.gethostname(), + host=list(self._local_ip_addresses.intersection(hosts))[0], share=self.environment[ohostedcons.StorageEnv.GLUSTER_SHARE_NAME], ) -- To view, visit https://gerrit.ovirt.org/41332 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5fcde43354268477e4c8a92ee29470750da7337a Gerrit-PatchSet: 1 Gerrit-Project: ovirt-hosted-engine-setup Gerrit-Branch: master Gerrit-Owner: Sandro Bonazzola <sbona...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches