コード例 #1
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def add_asd_disk(disk_id):
     """
     Adds an ASD to a disk
     :param disk_id: Identifier of the disk
     :type disk_id: str
     """
     mountpoints = FSTab.read()
     if disk_id not in mountpoints:
         raise BadRequest('Disk {0} is not yet initialized'.format(disk_id))
     with file_mutex('add_asd'):
         ASDController.create_asd(disk_id)
コード例 #2
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def restart_asd(disk_id, asd_id):
     """
     Restart an ASD
     :param disk_id: Identifier of the disk
     :type disk_id: str
     :param asd_id: Identifier of the ASD
     :type asd_id: str
     """
     API._log('Restarting ASD {0}'.format(asd_id))
     _ = disk_id
     ASDController.restart_asd(asd_id)
コード例 #3
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def restart_asd(disk_id, asd_id):
     """
     Restart an ASD
     :param disk_id: Identifier of the disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
     :type disk_id: str
     :param asd_id: Identifier of the ASD  (eg: bnAWEXuPHN5YJceCeZo7KxaQW86ixXd4, found under /mnt/alba-asd/WDCztMxmRqi6Hx21/)
     :type asd_id: str
     :return: None
     """
     API._logger.info('Restarting ASD {0}'.format(asd_id))
     _ = disk_id
     ASDController.restart_asd(asd_id=asd_id)
コード例 #4
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def add_asd_disk(disk_id):
     """
     Adds an ASD to a disk
     :param disk_id: Identifier of the disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
     :type disk_id: str
     :return: None
     """
     disk_data = DiskController.get_disk_data_by_alias(device_alias=disk_id)
     for partition_alias, mountpoint in FSTab.read().iteritems():
         if partition_alias in disk_data['partition_aliases']:
             with file_mutex('add_asd'):
                 ASDController.create_asd(partition_alias=partition_alias)
                 return
     raise BadRequest('Disk {0} is not yet initialized'.format(disk_data['aliases'][0]))
コード例 #5
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def list_asds():
     """
     List all ASDs
     :return: Information about all ASDs on local node
     :rtype: dict
     """
     return dict((partition_alias, ASDController.list_asds(mountpoint=mountpoint)) for partition_alias, mountpoint in FSTab.read().iteritems())
コード例 #6
0
 def asd_add(slot_id):
     # type: (str) -> None
     """
     Add an ASD to the slot specified
     :param slot_id: Identifier of the slot
     :type slot_id: str
     :return: None
     :rtype: NoneType
     """
     disk = DiskList.get_by_alias(slot_id)
     if disk.available is True:
         with file_mutex('add_disk'), file_mutex(
                 'disk_{0}'.format(slot_id)):
             DiskController.prepare_disk(disk=disk)
             disk = Disk(disk.id)
     with file_mutex('add_asd'):
         ASDController.create_asd(disk)
コード例 #7
0
 def slot_restart(slot_id):
     # type: (str) -> None
     """
    Restart a slot
    :param slot_id: Identifier of the slot  (eg: 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
    :type slot_id: str
    :return: None
    """
     disk = DiskList.get_by_alias(slot_id)
     with file_mutex('slot_{0}'.format(slot_id)):
         API._logger.info(
             'Got lock for restarting slot {0}'.format(slot_id))
         for asd in disk.asds:
             ASDController.stop_asd(asd=asd)
         DiskController.remount_disk(disk=disk)
         for asd in disk.asds:
             ASDController.start_asd(asd=asd)
コード例 #8
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def list_asds():
     """
     List all ASDs
     """
     asds = {}
     mountpoints = FSTab.read()
     for disk, mountpoint in mountpoints.iteritems():
         asds[disk] = ASDController.list_asds(mountpoint)
     return asds
コード例 #9
0
 def asd_restart(slot_id, asd_id):
     # type: (str, str) -> None
     """
     Restart an ASD
     :param slot_id: Identifier of the slot
     :type slot_id: str
     :param asd_id: Identifier of the ASD  (eg: bnAWEXuPHN5YJceCeZo7KxaQW86ixXd4, found under /mnt/alba-asd/WDCztMxmRqi6Hx21/)
     :type asd_id: str
     :return: None
     :rtype: NoneType
     """
     disk = DiskList.get_by_alias(slot_id)
     asds = [asd for asd in disk.asds if asd.asd_id == asd_id]
     if len(asds) != 1:
         raise HttpNotFoundException(
             error='asd_not_found',
             error_description='Could not find ASD {0} on Slot {1}'.format(
                 asd_id, slot_id))
     ASDController.restart_asd(asds[0])
コード例 #10
0
ファイル: update.py プロジェクト: yongshengma/alba-asdmanager
    def get_package_information(cls):
        """
        Retrieve the installed and candidate versions of all packages relevant for this repository (See PackageFactory.get_package_info)
        If installed version is lower than candidate version, this information is stored
        If installed version is equal or higher than candidate version we verify whether all relevant services have the correct binary active
        Whether a service has the correct binary version in use, we use the ServiceFactory.get_service_update_versions functionality

        In this function the services for each component / package combination are defined
        This service information consists out of:
            * Services to stop (before update) and start (after update of packages) -> 'services_stop_start'
            * Services to restart after update (post-update logic)                  -> 'services_post_update'
            * Down-times which will be caused due to service restarts               -> 'downtime'
            * Prerequisites that have not been met                                  -> 'prerequisites'

        The installed vs candidate version which is displayed always gives priority to the versions effectively installed on the system
        and not the versions as reported by the service files

        This combined information is then stored in the 'package_information' of the ALBA Node DAL object
        :return: Update information
        :rtype: dict
        """
        cls._logger.info('Refreshing update information')

        binaries = cls._package_manager.get_binary_versions(client=cls._local_client)
        update_info = {}
        package_info = PackageFactory.get_packages_to_update(client=cls._local_client)  # {'alba': {'openvstorage-sdm': {'installed': 'ee-1.6.1', 'candidate': 'ee-1.6.2'}}}
        cls._logger.debug('Binary versions found: {0}'.format(binaries))
        cls._logger.debug('Package info found: {0}'.format(package_info))
        for component, package_names in PackageFactory.get_package_info()['names'].iteritems():
            package_names = sorted(package_names)
            cls._logger.debug('Validating component {0} and related packages: {1}'.format(component, package_names))
            if component not in update_info:
                update_info[component] = copy.deepcopy(ServiceFactory.DEFAULT_UPDATE_ENTRY)
            svc_component_info = update_info[component]
            pkg_component_info = package_info.get(component, {})

            for package_name in package_names:
                cls._logger.debug('Validating package {0}'.format(package_name))
                if package_name in [PackageFactory.PKG_ALBA, PackageFactory.PKG_ALBA_EE]:
                    for service_name in sorted(list(ASDController.list_asd_services())) + sorted(list(MaintenanceController.get_services())):
                        service_version = ServiceFactory.get_service_update_versions(client=cls._local_client, service_name=service_name, binary_versions=binaries)
                        cls._logger.debug('Service {0} has version: {1}'.format(service_name, service_version))
                        # If package_name in pkg_component_info --> update available (installed <--> candidate)
                        # If service_version is not None --> service is running an older binary version
                        if package_name in pkg_component_info or service_version is not None:
                            svc_component_info['services_post_update'][20].append(service_name)
                            if service_version is not None and package_name not in svc_component_info['packages']:
                                svc_component_info['packages'][package_name] = service_version

                # Extend the service information with the package information related to this repository for current ALBA Node
                if package_name in pkg_component_info and package_name not in svc_component_info['packages']:
                    cls._logger.debug('Adding package {0} because it has an update available'.format(package_name))
                    svc_component_info['packages'][package_name] = pkg_component_info[package_name]
        cls._logger.info('Refreshed update information')
        return update_info
コード例 #11
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
    def delete_disk(disk_id):
        """
        Delete a disk
        :param disk_id: Identifier of the disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
        :type disk_id: str
        :return: None
        """
        try:
            disk_data = DiskController.get_disk_data_by_alias(device_alias=disk_id)
        except DiskNotFoundError:
            API._logger.warning('Disk with ID {0} is no longer detected on the filesystem'.format(disk_id))
            disk_data = {}

        if disk_data.get('available') is True:
            raise BadRequest('Disk not yet configured')

        if disk_data:
            alias = disk_data['aliases'][0]
            mountpoint = disk_data['mountpoint'] or None
            partition_aliases = disk_data['partition_aliases']
            API._logger.info('Deleting disk {0}'.format(alias))
        else:  # Disk is most likely missing from filesystem
            alias = None
            mountpoint = None
            partition_aliases = json.loads(request.form['partition_aliases'])
            API._logger.info('Deleting unknown disk with partition aliases "{0}"'.format('", "'.join(partition_aliases)))

        if mountpoint is None:  # 'lsblk' did not return mountpoint for the device, but perhaps it's still mounted according to FSTab
            for partition_alias, mtpt in FSTab.read().iteritems():
                if partition_alias in partition_aliases:
                    API._logger.warning('Disk with ID {0} is still mounted on {1} according to FSTab'.format(disk_id, mountpoint))
                    mountpoint = mtpt
                    break

        with file_mutex('disk_{0}'.format(disk_id)):
            if mountpoint is not None:
                for asd_id in ASDController.list_asds(mountpoint=mountpoint):
                    ASDController.remove_asd(asd_id=asd_id,
                                             mountpoint=mountpoint)
            DiskController.clean_disk(device_alias=alias,
                                      mountpoint=mountpoint,
                                      partition_aliases=partition_aliases)
コード例 #12
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def asd_delete(disk_id, asd_id):
     """
     Deletes an ASD on a given Disk
     :param disk_id: Identifier of the Disk
     :type disk_id: str
     :param asd_id: The ASD ID of the ASD to be removed
     :type asd_id: str
     """
     # Stop and remove service
     API._log('Removing services for disk {0}'.format(disk_id))
     mountpoints = FSTab.read()
     if disk_id not in mountpoints:
         raise BadRequest('Disk {0} is not yet initialized'.format(disk_id))
     all_asds = {}
     for mountpoint in mountpoints.values():
         all_asds.update(ASDController.list_asds(mountpoint))
     if asd_id not in all_asds:
         raise BadRequest('Could not find ASD {0} on disk {1}'.format(asd_id, disk_id))
     mountpoint = mountpoints[disk_id]
     ASDController.remove_asd(asd_id, mountpoint)
コード例 #13
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def list_asds_disk(disk_id):
     """
     Lists all ASDs on a given disk
     :param disk_id: Identifier of the disk
     :type disk_id: str
     """
     mountpoints = FSTab.read()
     if disk_id not in mountpoints:
         raise BadRequest('Disk {0} is not yet initialized'.format(disk_id))
     mountpoint = mountpoints[disk_id]
     return ASDController.list_asds(mountpoint)
コード例 #14
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def delete_disk(disk_id):
     """
     Delete a disk
     :param disk_id: Identifier of the disk
     :type disk_id: str
     """
     API._log('Deleting disk {0}'.format(disk_id))
     all_disks = DiskController.list_disks()
     if disk_id not in all_disks:
         raise BadRequest('Disk not available')
     if all_disks[disk_id]['available'] is True:
         raise BadRequest('Disk not yet configured')
     with file_mutex('disk_{0}'.format(disk_id)):
         mountpoints = FSTab.read()
         if disk_id in mountpoints:
             mountpoint = mountpoints[disk_id]
             asds = ASDController.list_asds(mountpoint)
             for asd_id in asds:
                 ASDController.remove_asd(asd_id, mountpoint)
             DiskController.clean_disk(disk_id, mountpoint)
コード例 #15
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def asd_delete(disk_id, asd_id):
     """
     Deletes an ASD on a given disk
     :param disk_id: Identifier of the Disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
     :type disk_id: str
     :param asd_id: Identifier of the ASD  (eg: bnAWEXuPHN5YJceCeZo7KxaQW86ixXd4, found under /mnt/alba-asd/WDCztMxmRqi6Hx21/)
     :type asd_id: str
     :return: None
     """
     disk_data = DiskController.get_disk_data_by_alias(device_alias=disk_id)
     alias = disk_data['aliases'][0]
     API._logger.info('Removing services for disk {0}'.format(alias))
     for partition_alias, mountpoint in FSTab.read().iteritems():
         if partition_alias in disk_data['partition_aliases']:
             if asd_id not in ASDController.list_asds(mountpoint=mountpoint):
                 raise BadRequest('Could not find ASD {0} on disk {1}'.format(asd_id, alias))
             ASDController.remove_asd(asd_id=asd_id,
                                      mountpoint=mountpoint)
             return
     raise BadRequest('Disk {0} is not yet initialized'.format(alias))
コード例 #16
0
 def asd_delete_by_slot(slot_id, asd_id):
     # type: (str, str) -> None
     """
     Delete an ASD from the slot specified
     :param slot_id: Identifier of the slot
     :type slot_id: str
     :param asd_id: Identifier of the ASD  (eg: bnAWEXuPHN5YJceCeZo7KxaQW86ixXd4, found under /mnt/alba-asd/WDCztMxmRqi6Hx21/)
     :type asd_id: str
     :return: None
     :rtype: NoneType
     """
     # If the disk would be missing, this will still return a disk object and the asds should be able to be found
     # Sync disk will only remove disks once they have no more asds linked to them
     disk = DiskList.get_by_alias(slot_id)
     asds = [asd for asd in disk.asds if asd.asd_id == asd_id]
     if len(asds) != 1:
         raise HttpNotFoundException(
             error='asd_not_found',
             error_description='Could not find ASD {0} on Slot {1}'.format(
                 asd_id, slot_id))
     ASDController.remove_asd(asds[0])
コード例 #17
0
 def asd_update(slot_id, asd_id, request_data):
     # type: (str, str, dict) -> None
     """
     Restart an ASD
     :param slot_id: Identifier of the slot
     :type slot_id: str
     :param asd_id: Identifier of the ASD  (eg: bnAWEXuPHN5YJceCeZo7KxaQW86ixXd4, found under /mnt/alba-asd/WDCztMxmRqi6Hx21/)
     :type asd_id: str
     :param request_data: Data about the request (given by the decorator)
     :type request_data: dict
     :return: None
     :rtype: NoneType
     """
     disk = DiskList.get_by_alias(slot_id)
     asds = [asd for asd in disk.asds if asd.asd_id == asd_id]
     if len(asds) != 1:
         raise HttpNotFoundException(
             error='asd_not_found',
             error_description='Could not find ASD {0} on Slot {1}'.format(
                 asd_id, slot_id))
     ASDController.update_asd(asd=asds[0],
                              update_data=request_data['update_data'])
コード例 #18
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def list_asds_disk(disk_id):
     """
     Lists all ASDs on a given disk
     :param disk_id: Identifier of the disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
     :type disk_id: str
     :return: ASD information for the specified disk
     :rtype: dict
     """
     disk_data = DiskController.get_disk_data_by_alias(device_alias=disk_id)
     for partition_alias, mountpoint in FSTab.read().iteritems():
         if partition_alias in disk_data['partition_aliases']:
             return ASDController.list_asds(mountpoint=mountpoint)
     raise BadRequest('Disk {0} is not yet initialized'.format(disk_data['aliases'][0]))
コード例 #19
0
    def clear_slot(slot_id):
        # type: (str) -> None
        """
        Clears a slot
        :param slot_id: Identifier of the slot
        :type slot_id: str
        :return: None
        :rtype: NoneType
        """
        try:
            disk = DiskList.get_by_alias(slot_id)
        except ObjectNotFoundException:
            API._logger.warning(
                'Disk with ID {0} is no longer present (or cannot be managed)'.
                format(slot_id))
            return None

        if disk.available is True:
            raise HttpNotAcceptableException(
                error='disk_not_configured',
                error_description='Disk not yet configured')

        with file_mutex('disk_{0}'.format(slot_id)):
            last_exception = None
            for asd in disk.asds:
                try:
                    ASDController.remove_asd(asd=asd)
                except Exception as ex:
                    last_exception = ex
            disk = Disk(disk.id)
            if len(disk.asds) == 0:
                DiskController.clean_disk(disk=disk)
            elif last_exception is not None:
                raise last_exception
            else:
                raise RuntimeError(
                    'Still some ASDs configured on Disk {0}'.format(slot_id))
コード例 #20
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def get_asd(disk_id, asd_id):
     """
     Gets an ASD
     :param disk_id: Identifier of the disk
     :type disk_id: str
     :param asd_id: Identifier of the ASD
     :type asd_id: str
     """
     mountpoints = FSTab.read()
     if disk_id not in mountpoints:
         raise BadRequest('Disk {0} is not yet initialized'.format(disk_id))
     mountpoint = mountpoints[disk_id]
     asds = ASDController.list_asds(mountpoint)
     if asd_id not in asds:
         raise BadRequest('ASD {0} could not be found on disk'.format(disk_id))
     return asds[asd_id]
コード例 #21
0
    def restart_services():
        """
        Restart the services ASD services and the Maintenance services
        :return: None
        """
        service_names = [service_name for service_name in ASDController.list_asd_services()]
        service_names.extend([service_name for service_name in MaintenanceController.get_services()])
        for service_name in service_names:
            status, _ = ServiceManager.get_service_status(service_name, SDMUpdateController._local_client)
            if status is False:
                SDMUpdateController._logger.warning('Found stopped service {0}. Will not start it.'.format(service_name))
                continue

            SDMUpdateController._logger.debug('Restarting service {0}'.format(service_name))
            try:
                ServiceManager.restart_service(service_name, SDMUpdateController._local_client)
            except CalledProcessError as cpe:
                SDMUpdateController._logger.debug('Failed to restart service {0} {1}'.format(service_name, cpe))
コード例 #22
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def get_asd(disk_id, asd_id):
     """
     Gets an ASD
     :param disk_id: Identifier of the disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
     :type disk_id: str
     :param asd_id: Identifier of the ASD  (eg: bnAWEXuPHN5YJceCeZo7KxaQW86ixXd4, found under /mnt/alba-asd/WDCztMxmRqi6Hx21/)
     :type asd_id: str
     :return: ASD information
     :rtype: dict
     """
     disk_data = DiskController.get_disk_data_by_alias(device_alias=disk_id)
     alias = disk_data['aliases'][0]
     for partition_alias, mountpoint in FSTab.read().iteritems():
         if partition_alias in disk_data['partition_aliases']:
             asds = ASDController.list_asds(mountpoint=mountpoint)
             if asd_id not in asds:
                 raise BadRequest('ASD {0} could not be found on disk'.format(alias))
             return asds[asd_id]
     raise BadRequest('Disk {0} is not yet initialized'.format(alias))
コード例 #23
0
ファイル: update.py プロジェクト: yongshengma/alba-asdmanager
    def restart_services(cls, service_names):
        """
        Restart the services specified
        :param service_names: Names of the services to restart
        :type service_names: list[str]
        :return: None
        :rtype: NoneType
        """
        if len(service_names) == 0:
            service_names = [service_name for service_name in ASDController.list_asd_services()]
            service_names.extend([service_name for service_name in MaintenanceController.get_services()])

        for service_name in service_names:
            cls._logger.warning('Verifying whether service {0} needs to be restarted'.format(service_name))
            if cls._service_manager.get_service_status(service_name, cls._local_client) != 'active':
                cls._logger.warning('Found stopped service {0}. Will not start it.'.format(service_name))
                continue

            cls._logger.info('Restarting service {0}'.format(service_name))
            try:
                cls._service_manager.restart_service(service_name, cls._local_client)
            except CalledProcessError:
                cls._logger.exception('Failed to restart service {0}'.format(service_name))
コード例 #24
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def restart_disk(disk_id):
     """
     Restart a disk
     :param disk_id: Identifier of the disk  (eg: '/dev/disk/by-path/pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0' or 'pci-0000:03:00.0-sas-0x5000c29f4cf04566-lun-0')
     :type disk_id: str
     :return: None
     """
     API._logger.info('Restarting disk {0}'.format(disk_id))
     disk_data = DiskController.get_disk_data_by_alias(device_alias=disk_id)
     alias = disk_data['aliases'][0]
     with file_mutex('disk_{0}'.format(disk_id)):
         API._logger.info('Got lock for restarting disk {0}'.format(alias))
         for partition_alias, mountpoint in FSTab.read().iteritems():
             if partition_alias in disk_data['partition_aliases']:
                 asds = ASDController.list_asds(mountpoint=mountpoint)
                 for asd_id in asds:
                     ASDController.stop_asd(asd_id=asd_id)
                 DiskController.remount_disk(device_alias=alias,
                                             mountpoint=mountpoint)
                 asds = ASDController.list_asds(mountpoint=mountpoint)
                 for asd_id in asds:
                     ASDController.start_asd(asd_id=asd_id)
                 break
コード例 #25
0
ファイル: api.py プロジェクト: DarumasLegs/alba-asdmanager
 def restart_disk(disk_id):
     """
     Restart a disk
     :param disk_id: Identifier of the disk
     :type disk_id: str
     """
     API._log('Restarting disk {0}'.format(disk_id))
     all_disks = DiskController.list_disks()
     if disk_id not in all_disks:
         raise BadRequest('Disk not available')
     if all_disks[disk_id]['available'] is False:
         raise BadRequest('Disk already configured')
     with file_mutex('disk_{0}'.format(disk_id)):
         API._log('Got lock for restarting disk {0}'.format(disk_id))
         mountpoints = FSTab.read()
         if disk_id in mountpoints:
             mountpoint = mountpoints[disk_id]
             asds = ASDController.list_asds(mountpoint)
             for asd_id in asds:
                 ASDController.stop_asd(asd_id)
             DiskController.remount_disk(disk_id, mountpoint)
             asds = ASDController.list_asds(mountpoint)
             for asd_id in asds:
                 ASDController.start_asd(asd_id)
コード例 #26
0
    def migrate(cls):
        # type: () -> None
        """
        Execute the migration logic.
        :return: None
        :rtype: NoneType
        """
        with file_mutex('package_update_pu'):
            local_client = SSHClient(endpoint='127.0.0.1', username='******')

            # Override the created openvstorage_sdm_id during package install, with currently available SDM ID
            if local_client.file_exists(BOOTSTRAP_FILE):
                with open(BOOTSTRAP_FILE) as bstr_file:
                    node_id = json.load(bstr_file)['node_id']
                local_client.file_write(filename='/etc/openvstorage_sdm_id',
                                        contents=node_id + '\n')
            else:
                with open('/etc/openvstorage_sdm_id', 'r') as id_file:
                    node_id = id_file.read().strip()

            key = '{0}/versions'.format(
                ASD_NODE_CONFIG_LOCATION.format(node_id))
            version = Configuration.get(key) if Configuration.exists(
                key) else 0

            asd_manager_service_name = 'asd-manager'
            if cls.service_manager.has_service(
                    asd_manager_service_name,
                    local_client) and cls.service_manager.get_service_status(
                        asd_manager_service_name, local_client) == 'active':
                cls.logger.info('Stopping asd-manager service')
                cls.service_manager.stop_service(asd_manager_service_name,
                                                 local_client)

            # @TODO: Move these migrations to alba_node.client.update_execute_migration_code()
            if version < cls.CURRENT_VERSION:
                try:
                    # DB migrations
                    from source.controllers.asd import ASDController
                    from source.controllers.disk import DiskController
                    from source.dal.asdbase import ASDBase
                    from source.dal.lists.asdlist import ASDList
                    from source.dal.lists.disklist import DiskList
                    from source.dal.objects.asd import ASD

                    if not local_client.file_exists('{0}/main.db'.format(
                            ASDBase.DATABASE_FOLDER)):
                        local_client.dir_create([ASDBase.DATABASE_FOLDER])

                    asd_map = dict(
                        (asd.asd_id, asd) for asd in ASDList.get_asds())
                    DiskController.sync_disks()
                    for disk in DiskList.get_usable_disks():
                        if disk.state == 'MISSING' or disk.mountpoint is None:
                            continue
                        for asd_id in local_client.dir_list(disk.mountpoint):
                            if asd_id in asd_map:
                                asd = asd_map[asd_id]
                            else:
                                asd = ASD()

                            asd.disk = disk
                            asd.asd_id = asd_id
                            asd.folder = asd_id
                            if asd.has_config:
                                if asd.port is None or asd.hosts is None:
                                    config = Configuration.get(
                                        key=asd.config_key)
                                    asd.port = config['port']
                                    asd.hosts = config.get('ips', [])
                                asd.save()

                    # Adjustment of open file descriptors for ASD/maintenance services to 8192
                    asd_service_names = list(ASDController.list_asd_services())
                    maintenance_service_names = list(
                        MaintenanceController.get_services())
                    for service_name in asd_service_names + maintenance_service_names:
                        if cls.service_manager.has_service(
                                name=service_name, client=local_client):
                            if cls.service_manager.__class__ == Systemd:
                                path = '/lib/systemd/system/{0}.service'.format(
                                    service_name)
                                check = 'LimitNOFILE=8192'
                            else:
                                path = '/etc/init/{0}.conf'.format(
                                    service_name)
                                check = 'limit nofile 8192 8192'

                            restart_required = False
                            if os.path.exists(path):
                                with open(path, 'r') as system_file:
                                    if check not in system_file.read():
                                        restart_required = True

                            if restart_required is False:
                                continue

                            configuration_key = ServiceFactory.SERVICE_CONFIG_KEY.format(
                                node_id, service_name)
                            if Configuration.exists(configuration_key):
                                # Rewrite the service file
                                cls.service_manager.add_service(
                                    name=ASDController.ASD_PREFIX
                                    if service_name in asd_service_names else
                                    MaintenanceController.MAINTENANCE_PREFIX,
                                    client=local_client,
                                    params=Configuration.get(
                                        configuration_key),
                                    target_name=service_name)

                                # Let the update know that the ASD / maintenance services need to be restarted
                                # Inside `if Configuration.exists`, because useless to rapport restart if we haven't rewritten service file
                                ExtensionsToolbox.edit_version_file(
                                    client=local_client,
                                    package_name='alba',
                                    old_run_file='{0}/{1}.version'.format(
                                        ServiceFactory.RUN_FILE_DIR,
                                        service_name))
                        if cls.service_manager.__class__ == Systemd:
                            local_client.run(['systemctl', 'daemon-reload'])

                    # Version 3: Addition of 'ExecReload' for ASD/maintenance SystemD services
                    if cls.service_manager.__class__ == Systemd:  # Upstart does not have functionality to reload a process' configuration
                        reload_daemon = False
                        asd_service_names = list(
                            ASDController.list_asd_services())
                        maintenance_service_names = list(
                            MaintenanceController.get_services())
                        for service_name in asd_service_names + maintenance_service_names:
                            if not cls.service_manager.has_service(
                                    name=service_name, client=local_client):
                                continue

                            path = '/lib/systemd/system/{0}.service'.format(
                                service_name)
                            if os.path.exists(path):
                                with open(path, 'r') as system_file:
                                    if 'ExecReload' not in system_file.read():
                                        reload_daemon = True
                                        configuration_key = ServiceFactory.SERVICE_CONFIG_KEY.format(
                                            node_id, service_name)
                                        if Configuration.exists(
                                                configuration_key):
                                            # No need to edit the service version file, since this change only requires a daemon-reload
                                            cls.service_manager.add_service(
                                                name=ASDController.ASD_PREFIX
                                                if service_name
                                                in asd_service_names else
                                                MaintenanceController.
                                                MAINTENANCE_PREFIX,
                                                client=local_client,
                                                params=Configuration.get(
                                                    configuration_key),
                                                target_name=service_name)
                        if reload_daemon is True:
                            local_client.run(['systemctl', 'daemon-reload'])

                    # Version 6: Introduction of Active Drive
                    all_local_ips = OSFactory.get_manager().get_ip_addresses(
                        client=local_client)
                    for asd in ASDList.get_asds():
                        if asd.has_config:
                            asd_config = Configuration.get(asd.config_key)
                            if 'multicast' not in asd_config:
                                asd_config['multicast'] = None
                            if 'ips' in asd_config:
                                asd_ips = asd_config['ips'] or all_local_ips
                            else:
                                asd_ips = all_local_ips
                            asd.hosts = asd_ips
                            asd_config['ips'] = asd_ips
                            Configuration.set(asd.config_key, asd_config)
                            asd.save()

                    # Version 7: Moving flask certificate files to config dir
                    for file_name in [
                            'passphrase', 'server.crt', 'server.csr',
                            'server.key'
                    ]:
                        if local_client.file_exists(
                                '/opt/asd-manager/source/{0}'.format(
                                    file_name)):
                            local_client.file_move(
                                source_file_name='/opt/asd-manager/source/{0}'.
                                format(file_name),
                                destination_file_name=
                                '/opt/asd-manager/config/{0}'.format(
                                    file_name))
                except:
                    cls.logger.exception(
                        'Error while executing post-update code on node {0}'.
                        format(node_id))
            Configuration.set(key, cls.CURRENT_VERSION)

            if cls.service_manager.has_service(
                    asd_manager_service_name,
                    local_client) and cls.service_manager.get_service_status(
                        asd_manager_service_name, local_client) != 'active':
                cls.logger.info('Starting asd-manager service')
                cls.service_manager.start_service(asd_manager_service_name,
                                                  local_client)

        cls.logger.info('Post-update logic executed')
コード例 #27
0
ファイル: update.py プロジェクト: yongshengma/alba-asdmanager
    def execute_migration_code(cls):
        # type: () -> None
        """
        Run some migration code after an update has been done
        :return: None
        :rtype: NoneType
        """
        cls._logger.info('Starting out of band migrations for SDM nodes')

        ###########################
        # Start crucial migration #
        ###########################

        # Removal of bootstrap file and store API IP, API port and node ID in SQLite DB
        try:
            if cls._local_client.file_exists(BOOTSTRAP_FILE):
                cls._logger.info('Bootstrap file still exists. Retrieving node ID')
                with open(BOOTSTRAP_FILE) as bstr_file:
                    node_id = json.load(bstr_file)['node_id']
            else:
                node_id = SettingList.get_setting_by_code(code='node_id').value
        except Exception:
            cls._logger.exception('Unable to determine the node ID, cannot migrate')
            raise

        try:
            api_settings_map = {'api_ip': 'ip', 'api_port': 'port'}  # Map settings code to keys in the Config management
            required_settings = ['node_id', 'migration_version'] + api_settings_map.keys()
            for settings_code in required_settings:
                try:
                    _ = SettingList.get_setting_by_code(settings_code)
                except ObjectNotFoundException:
                    cls._logger.info('Missing required settings: {0}'.format(settings_code))
                    if settings_code == 'node_id':
                        value = node_id
                    elif settings_code in api_settings_map.keys():
                        # Information must be extracted from Configuration
                        main_config = Configuration.get(ASD_NODE_CONFIG_MAIN_LOCATION.format(node_id))
                        value = main_config[api_settings_map[settings_code]]
                    elif settings_code == 'migration_version':
                        # Introduce version for ASD Manager migration code
                        value = 0
                    else:
                        raise NotImplementedError('No action implemented for setting {0}'.format(settings_code))

                    cls._logger.info('Modeling Setting with code {0} and value {1}'.format(settings_code, value))
                    setting = Setting()
                    setting.code = settings_code
                    setting.value = value
                    setting.save()

            if cls._local_client.file_exists(BOOTSTRAP_FILE):
                cls._logger.info('Removing the bootstrap file')
                cls._local_client.file_delete(BOOTSTRAP_FILE)
        except Exception:
            cls._logger.exception('Error during migration of code settings. Unable to proceed')
            raise

        ###############################
        # Start non-crucial migration #
        ###############################

        errors = []
        migration_setting = SettingList.get_setting_by_code(code='migration_version')
        # Add installed package_name in version files and additional string replacements in service files
        try:
            if migration_setting.value < 1:
                cls._logger.info('Adding additional information to service files')
                edition = Configuration.get_edition()
                if edition == PackageFactory.EDITION_ENTERPRISE:
                    for version_file_name in cls._local_client.file_list(directory=ServiceFactory.RUN_FILE_DIR):
                        version_file_path = '{0}/{1}'.format(ServiceFactory.RUN_FILE_DIR, version_file_name)
                        contents = cls._local_client.file_read(filename=version_file_path)
                        if '{0}='.format(PackageFactory.PKG_ALBA) in contents:
                            contents = contents.replace(PackageFactory.PKG_ALBA, PackageFactory.PKG_ALBA_EE)
                            cls._local_client.file_write(filename=version_file_path, contents=contents)

                    node_id = SettingList.get_setting_by_code(code='node_id').value
                    asd_services = list(ASDController.list_asd_services())
                    maint_services = list(MaintenanceController.get_services())
                    for service_name in asd_services + maint_services:
                        config_key = ServiceFactory.SERVICE_CONFIG_KEY.format(node_id, service_name)
                        if Configuration.exists(key=config_key):
                            config = Configuration.get(key=config_key)
                            if 'RUN_FILE_DIR' in config:
                                continue
                            config['RUN_FILE_DIR'] = ServiceFactory.RUN_FILE_DIR
                            config['ALBA_PKG_NAME'] = PackageFactory.PKG_ALBA_EE
                            config['ALBA_VERSION_CMD'] = PackageFactory.VERSION_CMD_ALBA
                            Configuration.set(key=config_key, value=config)
                            cls._service_manager.regenerate_service(name=ASDController.ASD_PREFIX if service_name in asd_services else MaintenanceController.MAINTENANCE_PREFIX,
                                                                    client=cls._local_client,
                                                                    target_name=service_name)
        except Exception as ex:
            cls._logger.exception('Failed to regenerate the ASD and Maintenance services')
            errors.append(ex)

        try:
            if migration_setting.value < 2:
                if System.get_component_identifier() not in Configuration.get(Configuration.get_registration_key(), default=[]):
                    Configuration.register_usage(System.get_component_identifier())
        except Exception as ex:
            cls._logger.exception('Failed to register the asd-manager')
            errors.append(ex)

        if len(errors) == 0:
            cls._logger.info('No errors during non-crucial migration. Saving the migration setting')
            # Save migration settings when no errors occurred
            migration_setting = SettingList.get_setting_by_code(code='migration_version')
            migration_setting.value = 2
            migration_setting.save()

        cls._logger.info('Finished out of band migrations for SDM nodes')
コード例 #28
0
def remove(silent=None):
    """
    Interactive removal part for the ASD manager
    :param silent: If silent == '--force-yes' no question will be asked to confirm the removal
    :type silent: str
    :return: None
    :rtype: NoneType
    """
    _print_and_log(message='\n' +
                   Interactive.boxed_message(['ASD Manager removal']))

    local_client = SSHClient(endpoint='127.0.0.1', username='******')
    if not local_client.file_exists(
            filename='{0}/main.db'.format(Setting.DATABASE_FOLDER)):
        _print_and_log(level='error',
                       message='\n' + Interactive.boxed_message(
                           ['The ASD Manager has already been removed']))
        sys.exit(1)

    _print_and_log(message=' - Validating configuration management')
    try:
        Configuration.list(key='ovs')
    except:
        _print_and_log(
            level='exception',
            message='\n' +
            Interactive.boxed_message(['Could not connect to Arakoon']))
        sys.exit(1)

    _print_and_log(message='  - Retrieving ASD information')
    all_asds = {}
    try:
        all_asds = ASDList.get_asds()
    except:
        _print_and_log(level='exception',
                       message='  - Failed to retrieve the ASD information')

    interactive = silent != '--force-yes'
    if interactive is True:
        message = 'Are you sure you want to continue?'
        if len(all_asds) > 0:
            _print_and_log(message='\n\n+++ ALERT +++\n', level='warning')
            message = 'DATA LOSS possible if proceeding! Continue?'

        proceed = Interactive.ask_yesno(message=message, default_value=False)
        if proceed is False:
            _print_and_log(level='error',
                           message='\n' +
                           Interactive.boxed_message(['Abort removal']))
            sys.exit(1)

    if len(all_asds) > 0:
        _print_and_log(message=' - Removing disks')
        for disk in DiskList.get_disks():
            if disk.available is True:
                continue
            try:
                _print_and_log(
                    message='    - Retrieving ASD information for disk {0}'.
                    format(disk.name))
                for asd in disk.asds:
                    _print_and_log(
                        message='      - Removing ASD {0}'.format(asd.name))
                    ASDController.remove_asd(asd)
                DiskController.clean_disk(disk)
            except Exception:
                _print_and_log(level='exception',
                               message='    - Deleting ASDs failed')

    _print_and_log(message=' - Removing services')
    service_manager = ServiceFactory.get_manager()
    for service in MaintenanceController.get_services():
        service_name = service
        _print_and_log(
            message='    - Removing service {0}'.format(service_name))
        guid = None
        for alba_backend_guid in Configuration.list(key='/ovs/alba/backends'):
            for maintenance_service_name in Configuration.list(
                    key='/ovs/alba/backends/{0}/maintenance/'.format(
                        alba_backend_guid)):
                if maintenance_service_name == service_name:
                    guid = alba_backend_guid
                    break
        MaintenanceController.remove_maintenance_service(
            name=service_name, alba_backend_guid=guid)

    for service_name in [WATCHER_SERVICE, MANAGER_SERVICE]:
        if service_manager.has_service(name=service_name, client=local_client):
            _print_and_log(
                message='   - Removing service {0}'.format(service_name))
            service_manager.stop_service(name=service_name,
                                         client=local_client)
            service_manager.remove_service(name=service_name,
                                           client=local_client)

    _print_and_log(message=' - Removing from configuration management')
    remaining_users = Configuration.uninitialize()
    if not remaining_users:
        local_client.file_delete(filenames=CACC_LOCATION)

    local_client.file_delete(
        filenames='{0}/main.db'.format(Setting.DATABASE_FOLDER))
    _print_and_log(
        message='\n' +
        Interactive.boxed_message(['ASD Manager removal completed']))
コード例 #29
0
    def get_package_information():
        """
        Retrieve information about the currently installed versions of the core packages
        Retrieve information about the versions to which each package can potentially be updated
        If installed version is different from candidate version --> store this information in model

        Additionally if installed version is identical to candidate version, check the services with a 'run' file
        Verify whether the running version is identical to the candidate version
        If different --> store this information in the model

        Result: Every package with updates or which requires services to be restarted is stored in the model

        :return: Package information
        :rtype: dict
        """
        binaries = PackageManager.get_binary_versions(client=SDMUpdateController._local_client, package_names=['alba'])
        installed = PackageManager.get_installed_versions(client=SDMUpdateController._local_client, package_names=PackageManager.SDM_PACKAGE_NAMES)
        candidate = PackageManager.get_candidate_versions(client=SDMUpdateController._local_client, package_names=PackageManager.SDM_PACKAGE_NAMES)
        if set(installed.keys()) != set(PackageManager.SDM_PACKAGE_NAMES) or set(candidate.keys()) != set(PackageManager.SDM_PACKAGE_NAMES):
            raise RuntimeError('Failed to retrieve the installed and candidate versions for packages: {0}'.format(', '.join(PackageManager.SDM_PACKAGE_NAMES)))

        package_info = {}
        default_entry = {'candidate': None,
                         'installed': None,
                         'services_to_restart': []}

        #                     component: package_name: services_with_run_file
        for component, info in {'alba': {'alba': list(ASDController.list_asd_services()) + list(MaintenanceController.get_services()),
                                         'openvstorage-sdm': []}}.iteritems():
            component_info = {}
            for package, services in info.iteritems():
                for service in services:
                    version_file = '/opt/asd-manager/run/{0}.version'.format(service)
                    if not SDMUpdateController._local_client.file_exists(version_file):
                        SDMUpdateController._logger.warning('Failed to find a version file in /opt/asd-manager/run for service {0}'.format(service))
                        continue
                    package_name = package
                    running_versions = SDMUpdateController._local_client.file_read(version_file).strip()
                    for version in running_versions.split(';'):
                        if '=' in version:
                            package_name = version.split('=')[0]
                            running_version = version.split('=')[1]
                        else:
                            running_version = version

                        if package_name not in PackageManager.SDM_PACKAGE_NAMES:
                            raise ValueError('Unknown package dependency found in {0}'.format(version_file))
                        if package_name not in binaries:
                            raise RuntimeError('Binary version for package {0} was not retrieved'.format(package_name))

                        if running_version != binaries[package_name]:
                            if package_name not in component_info:
                                component_info[package_name] = copy.deepcopy(default_entry)
                            component_info[package_name]['installed'] = running_version
                            component_info[package_name]['candidate'] = binaries[package_name]
                            component_info[package_name]['services_to_restart'].append(service)

                if installed[package] != candidate[package] and package not in component_info:
                    component_info[package] = copy.deepcopy(default_entry)
                    component_info[package]['installed'] = installed[package]
                    component_info[package]['candidate'] = candidate[package]
            if component_info:
                package_info[component] = component_info
        return package_info
コード例 #30
0
ファイル: api.py プロジェクト: openvstorage/alba-asdmanager
 def list_asd_services():
     """ List all ASD service names """
     API._logger.info('Listing ASD services')
     return {'services': list(ASDController.list_asd_services())}