From fcd8271c5b6d4a9df2b1db93f15e261fc757fa3e Mon Sep 17 00:00:00 2001 From: Alessandro Pilotti Date: Thu, 28 Mar 2013 23:57:20 +0200 Subject: [PATCH] pylint and pep8 --- cloudbaseinit/init.py | 30 +++---- cloudbaseinit/metadata/factory.py | 25 +++--- cloudbaseinit/metadata/services/base.py | 10 +-- .../services/configdrive/configdrive.py | 21 ++--- .../metadata/services/configdrive/manager.py | 46 ++++++----- .../configdrive/windows/disk/physical_disk.py | 5 +- .../configdrive/windows/disk/virtual_disk.py | 32 ++++---- cloudbaseinit/metadata/services/ec2service.py | 80 ++++++++++--------- .../metadata/services/httpservice.py | 11 ++- cloudbaseinit/osutils/base.py | 11 +-- cloudbaseinit/osutils/factory.py | 7 +- cloudbaseinit/osutils/posix.py | 5 +- cloudbaseinit/osutils/windows.py | 45 ++++++----- cloudbaseinit/plugins/base.py | 1 + cloudbaseinit/plugins/factory.py | 10 ++- cloudbaseinit/plugins/windows/createuser.py | 18 ++--- .../plugins/windows/networkconfig.py | 27 ++++--- cloudbaseinit/plugins/windows/sethostname.py | 9 +-- .../plugins/windows/sshpublickeys.py | 8 +- cloudbaseinit/plugins/windows/userdata.py | 13 +-- cloudbaseinit/shell.py | 7 +- cloudbaseinit/utils/crypt.py | 1 + setup.py | 46 +++++------ 23 files changed, 244 insertions(+), 224 deletions(-) diff --git a/cloudbaseinit/init.py b/cloudbaseinit/init.py index c8bc9531..9fc2e195 100644 --- a/cloudbaseinit/init.py +++ b/cloudbaseinit/init.py @@ -14,16 +14,11 @@ # License for the specific language governing permissions and limitations # under the License. -import sys - -from cloudbaseinit.metadata.factory import * -from cloudbaseinit.openstack.common import cfg +from cloudbaseinit.metadata import factory as metadata_factory from cloudbaseinit.openstack.common import log as logging -from cloudbaseinit.osutils.factory import * -from cloudbaseinit.plugins.factory import * -from cloudbaseinit.utils import * +from cloudbaseinit.osutils import factory as osutils_factory +from cloudbaseinit.plugins import factory as plugins_factory -CONF = cfg.CONF LOG = logging.getLogger(__name__) @@ -35,18 +30,19 @@ class InitManager(object): def _mark_as_configured(self, osutils): osutils.set_config_value(self._config_done_key, 1) - + def configure_host(self): - osutils = OSUtilsFactory().get_os_utils() - + osutils = osutils_factory.OSUtilsFactory().get_os_utils() + if self._is_already_configured(osutils): LOG.info('Host already configured, skipping configuration') return - - plugins = PluginFactory().load_plugins() - service = MetadataServiceFactory().get_metadata_service() + + plugins = plugins_factory.PluginFactory().load_plugins() + mdsf = metadata_factory.MetadataServiceFactory() + service = mdsf.get_metadata_service() LOG.info('Metadata service loaded: \'%s\'' % - service.__class__.__name__) + service.__class__.__name__) reboot_required = False try: @@ -59,12 +55,12 @@ class InitManager(object): reboot_required = True except Exception, ex: LOG.error('plugin \'%(plugin_name)s\' failed ' - 'with error \'%(ex)s\'' % locals()) + 'with error \'%(ex)s\'' % locals()) finally: service.cleanup() self._mark_as_configured(osutils) - + if reboot_required: try: osutils.reboot() diff --git a/cloudbaseinit/metadata/factory.py b/cloudbaseinit/metadata/factory.py index 26e40e77..ebc0cc1a 100644 --- a/cloudbaseinit/metadata/factory.py +++ b/cloudbaseinit/metadata/factory.py @@ -19,16 +19,18 @@ from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.utils import classloader opts = [ - cfg.ListOpt('metadata_services', default=[ - 'cloudbaseinit.metadata.services.httpservice.HttpService', - 'cloudbaseinit.metadata.services.configdrive.configdrive.' - 'ConfigDriveService', - 'cloudbaseinit.metadata.services.ec2service.EC2Service' - ], - help='List of enabled metadata service classes, ' - 'to be tested fro availability in the provided order. ' - 'The first available service will be used to retrieve metadata') - ] + cfg.ListOpt('metadata_services', + default=[ + 'cloudbaseinit.metadata.services.httpservice.HttpService', + 'cloudbaseinit.metadata.services.configdrive.configdrive.' + 'ConfigDriveService', + 'cloudbaseinit.metadata.services.ec2service.EC2Service' + ], + help='List of enabled metadata service classes, ' + 'to be tested fro availability in the provided order. ' + 'The first available service will be used to retrieve ' + 'metadata') +] CONF = cfg.CONF CONF.register_opts(opts) @@ -46,6 +48,5 @@ class MetadataServiceFactory(object): return service except Exception, ex: LOG.error('Failed to load metadata service \'%(class_path)s\' ' - 'with error: %(ex)s'% - locals()) + 'with error: %(ex)s' % locals()) raise Exception("No available service found") diff --git a/cloudbaseinit/metadata/services/base.py b/cloudbaseinit/metadata/services/base.py index 9a301540..338b0687 100644 --- a/cloudbaseinit/metadata/services/base.py +++ b/cloudbaseinit/metadata/services/base.py @@ -24,12 +24,12 @@ from cloudbaseinit.openstack.common import log as logging opts = [ cfg.IntOpt('retry_count', default=5, - help='Max. number of attempts for fetching metadata in ' - 'case of transient errors'), + help='Max. number of attempts for fetching metadata in ' + 'case of transient errors'), cfg.FloatOpt('retry_count_interval', default=4, - help='Interval between attempts in case of transient errors, ' - 'expressed in seconds'), - ] + help='Interval between attempts in case of transient errors, ' + 'expressed in seconds'), +] CONF = cfg.CONF CONF.register_opts(opts) diff --git a/cloudbaseinit/metadata/services/configdrive/configdrive.py b/cloudbaseinit/metadata/services/configdrive/configdrive.py index 330817d7..b8f04182 100644 --- a/cloudbaseinit/metadata/services/configdrive/configdrive.py +++ b/cloudbaseinit/metadata/services/configdrive/configdrive.py @@ -14,23 +14,22 @@ # License for the specific language governing permissions and limitations # under the License. -import json import os import shutil import tempfile import uuid -from cloudbaseinit.metadata.services.base import * +from cloudbaseinit.metadata.services import base from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import log as logging -from manager import * +from cloudbaseinit.metadata.services.configdrive import manager opts = [ cfg.BoolOpt('config_drive_raw_hhd', default=True, - help='Look for an ISO config drive in raw HDDs'), + help='Look for an ISO config drive in raw HDDs'), cfg.BoolOpt('config_drive_cdrom', default=True, - help='Look for a config drive in the attached cdrom drives'), - ] + help='Look for a config drive in the attached cdrom drives'), +] CONF = cfg.CONF CONF.register_opts(opts) @@ -38,7 +37,7 @@ CONF.register_opts(opts) LOG = logging.getLogger(__name__) -class ConfigDriveService(BaseMetadataService): +class ConfigDriveService(base.BaseMetadataService): def __init__(self): self._metadata_path = None @@ -47,12 +46,14 @@ class ConfigDriveService(BaseMetadataService): target_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4())) - mgr = ConfigDriveManager() + mgr = manager.ConfigDriveManager() found = mgr.get_config_drive_files(target_path, - CONF.config_drive_raw_hhd, CONF.config_drive_cdrom) + CONF.config_drive_raw_hhd, + CONF.config_drive_cdrom) if found: self._metadata_path = target_path - LOG.debug('Metadata copied to folder: \'%s\'' % self._metadata_path) + LOG.debug('Metadata copied to folder: \'%s\'' % + self._metadata_path) return found def _get_data(self, path): diff --git a/cloudbaseinit/metadata/services/configdrive/manager.py b/cloudbaseinit/metadata/services/configdrive/manager.py index 32f9970c..77ee233e 100644 --- a/cloudbaseinit/metadata/services/configdrive/manager.py +++ b/cloudbaseinit/metadata/services/configdrive/manager.py @@ -26,8 +26,10 @@ from ctypes import wintypes from cloudbaseinit.openstack.common import log as logging -from windows.disk import physical_disk -from windows.disk import virtual_disk +from cloudbaseinit.metadata.services.configdrive.windows.disk \ + import physical_disk +from cloudbaseinit.metadata.services.configdrive.windows.disk \ + import virtual_disk LOG = logging.getLogger(__name__) @@ -38,41 +40,45 @@ class ConfigDriveManager(object): conn = wmi.WMI(moniker='//./root/cimv2') q = conn.query('SELECT DeviceID FROM Win32_DiskDrive') for r in q: - l.append(r.DeviceID) + l.append(r.DeviceID) return l def _get_config_drive_cdrom_mount_point(self): conn = wmi.WMI(moniker='//./root/cimv2') - q = conn.query('SELECT Drive FROM Win32_CDROMDrive WHERE MediaLoaded = True') + q = conn.query('SELECT Drive FROM Win32_CDROMDrive WHERE ' + 'MediaLoaded = True') for r in q: drive = r.Drive + '\\' - q1 = conn.query('SELECT Label FROM Win32_Volume WHERE Name = \'%(drive)s\'' % locals()) + q1 = conn.query('SELECT Label FROM Win32_Volume WHERE ' + 'Name = \'%(drive)s\'' % locals()) for r1 in q1: if r1.Label == "config-2" and \ - os.path.exists(os.path.join(drive, 'openstack\\latest\\meta_data.json')): + os.path.exists(os.path.join(drive, + 'openstack\\latest\\' + 'meta_data.json')): return drive return None def _c_char_array_to_c_ushort(self, buf, offset): low = ctypes.cast(buf[offset], - ctypes.POINTER(wintypes.WORD)).contents + ctypes.POINTER(wintypes.WORD)).contents high = ctypes.cast(buf[offset + 1], - ctypes.POINTER(wintypes.WORD)).contents + ctypes.POINTER(wintypes.WORD)).contents return (high.value << 8) + low.value def _get_iso_disk_size(self, phys_disk): geom = phys_disk.get_geometry() - if geom.MediaType != Win32_DiskGeometry.FixedMedia: + if geom.MediaType != physical_disk.Win32_DiskGeometry.FixedMedia: return None disk_size = geom.Cylinders * geom.TracksPerCylinder * \ geom.SectorsPerTrack * geom.BytesPerSector - boot_record_off = 0x8000; - id_off = 1; - volume_size_off = 80; - block_size_off = 128; + boot_record_off = 0x8000 + id_off = 1 + volume_size_off = 80 + block_size_off = 128 iso_id = 'CD001' offset = boot_record_off / geom.BytesPerSector * geom.BytesPerSector @@ -85,7 +91,7 @@ class ConfigDriveManager(object): (buf, bytes_read) = phys_disk.read(bytes_to_read) buf_off = boot_record_off - offset + id_off - if iso_id != buf[buf_off : buf_off + len(iso_id)]: + if iso_id != buf[buf_off: buf_off + len(iso_id)]: return None buf_off = boot_record_off - offset + volume_size_off @@ -136,7 +142,7 @@ class ConfigDriveManager(object): iso_file_size = self._get_iso_disk_size(phys_disk) if iso_file_size: self._write_iso_file(phys_disk, iso_file_path, - iso_file_size) + iso_file_size) iso_disk_found = True break except: @@ -148,14 +154,15 @@ class ConfigDriveManager(object): def _os_supports_iso_virtual_disks(self): # Feature supported starting from Windows 8 / 2012 - ver = sys.getwindowsversion(); + ver = sys.getwindowsversion() supported = (ver[0] >= 6 and ver[1] >= 2) if not supported: LOG.debug('ISO virtual disks are not supported on ' - 'this version of Windows') + 'this version of Windows') return supported - def get_config_drive_files(self, target_path, check_raw_hhd=True, check_cdrom=True): + def get_config_drive_files(self, target_path, check_raw_hhd=True, + check_cdrom=True): config_drive_found = False if check_raw_hhd and self._os_supports_iso_virtual_disks(): LOG.debug('Looking for Config Drive in raw HDDs') @@ -178,7 +185,7 @@ class ConfigDriveManager(object): def _get_conf_drive_from_raw_hdd(self, target_path): config_drive_found = False iso_file_path = os.path.join(tempfile.gettempdir(), - str(uuid.uuid4()) + '.iso') + str(uuid.uuid4()) + '.iso') try: if self._extract_iso_disk_file(iso_file_path): self._copy_iso_files(iso_file_path, target_path) @@ -187,4 +194,3 @@ class ConfigDriveManager(object): if os.path.exists(iso_file_path): os.remove(iso_file_path) return config_drive_found - diff --git a/cloudbaseinit/metadata/services/configdrive/windows/disk/physical_disk.py b/cloudbaseinit/metadata/services/configdrive/windows/disk/physical_disk.py index 3e424861..438ba949 100644 --- a/cloudbaseinit/metadata/services/configdrive/windows/disk/physical_disk.py +++ b/cloudbaseinit/metadata/services/configdrive/windows/disk/physical_disk.py @@ -93,7 +93,8 @@ class PhysicalDisk(object): low = wintypes.DWORD(offset & 0xFFFFFFFFL) ret_val = kernel32.SetFilePointer(self._handle, low, - ctypes.byref(high), self.FILE_BEGIN) + ctypes.byref(high), + self.FILE_BEGIN) if ret_val == self.INVALID_SET_FILE_POINTER: raise Exception("Seek error") @@ -101,7 +102,7 @@ class PhysicalDisk(object): buf = ctypes.create_string_buffer(bytes_to_read) bytes_read = wintypes.DWORD() ret_val = kernel32.ReadFile(self._handle, buf, bytes_to_read, - ctypes.byref(bytes_read), 0) + ctypes.byref(bytes_read), 0) if not ret_val: raise Exception("Read exception") return (buf, bytes_read.value) diff --git a/cloudbaseinit/metadata/services/configdrive/windows/disk/virtual_disk.py b/cloudbaseinit/metadata/services/configdrive/windows/disk/virtual_disk.py index 16f284ab..e63ed220 100644 --- a/cloudbaseinit/metadata/services/configdrive/windows/disk/virtual_disk.py +++ b/cloudbaseinit/metadata/services/configdrive/windows/disk/virtual_disk.py @@ -36,7 +36,7 @@ def get_WIN32_VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT(): guid.Data1 = 0xec984aec guid.Data2 = 0xa0f9 guid.Data3 = 0x47e9 - ByteArray8 = wintypes.BYTE * 8; + ByteArray8 = wintypes.BYTE * 8 guid.Data4 = ByteArray8(0x90, 0x1f, 0x71, 0x41, 0x5a, 0x66, 0x34, 0x5b) return guid @@ -77,31 +77,34 @@ class VirtualDisk(object): vst.VendorId = get_WIN32_VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT() handle = wintypes.HANDLE() - ret_val = virtdisk.OpenVirtualDisk(ctypes.byref(vst), ctypes.c_wchar_p(self._path), - self.VIRTUAL_DISK_ACCESS_ATTACH_RO | self.VIRTUAL_DISK_ACCESS_READ, - self.OPEN_VIRTUAL_DISK_FLAG_NONE, 0, ctypes.byref(handle)) + ret_val = virtdisk.OpenVirtualDisk(ctypes.byref(vst), + ctypes.c_wchar_p(self._path), + self.VIRTUAL_DISK_ACCESS_ATTACH_RO | + self.VIRTUAL_DISK_ACCESS_READ, + self.OPEN_VIRTUAL_DISK_FLAG_NONE, 0, + ctypes.byref(handle)) if ret_val: raise Exception("Cannot open virtual disk") self._handle = handle def attach(self): - ret_val = virtdisk.AttachVirtualDisk(self._handle, 0, - self.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, - 0, 0, 0) + ret_val = virtdisk.AttachVirtualDisk( + self._handle, 0, self.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, 0, 0, 0) if ret_val: raise Exception("Cannot attach virtual disk") def detach(self): - ret_val = virtdisk.DetachVirtualDisk(self._handle, - self.DETACH_VIRTUAL_DISK_FLAG_NONE, 0) + ret_val = virtdisk.DetachVirtualDisk( + self._handle, self.DETACH_VIRTUAL_DISK_FLAG_NONE, 0) if ret_val: raise Exception("Cannot detach virtual disk") def get_physical_path(self): buf = ctypes.create_unicode_buffer(1024) - bufLen = wintypes.DWORD(ctypes.sizeof(buf)); + bufLen = wintypes.DWORD(ctypes.sizeof(buf)) ret_val = virtdisk.GetVirtualDiskPhysicalPath(self._handle, - ctypes.byref(bufLen), buf) + ctypes.byref(bufLen), + buf) if ret_val: raise Exception("Cannot get virtual disk physical path") return buf.value @@ -120,12 +123,13 @@ class VirtualDisk(object): i = 0 while not mount_point and i < buf_len: - curr_drive = ctypes.wstring_at(ctypes.addressof(buf) + \ - i * ctypes.sizeof(wintypes.WCHAR))[:-1] + curr_drive = ctypes.wstring_at(ctypes.addressof(buf) + i * + ctypes.sizeof(wintypes.WCHAR))[:-1] dev = ctypes.create_unicode_buffer(2048) ret_val = kernel32.QueryDosDeviceW(curr_drive, dev, - ctypes.sizeof(dev) / ctypes.sizeof(wintypes.WCHAR)) + ctypes.sizeof(dev) / + ctypes.sizeof(wintypes.WCHAR)) if not ret_val: raise Exception("Cannot query NT device") diff --git a/cloudbaseinit/metadata/services/ec2service.py b/cloudbaseinit/metadata/services/ec2service.py index 83901add..3e66ebfe 100644 --- a/cloudbaseinit/metadata/services/ec2service.py +++ b/cloudbaseinit/metadata/services/ec2service.py @@ -27,27 +27,29 @@ opts = [ cfg.StrOpt('ec2_metadata_base_url', default='http://169.254.169.254/2009-04-04/', help='The base URL where the service looks for metadata'), - ] +] -ec2nodes = ['ami-id', 'ami-launch-index', 'ami-manifest-path', 'ancestor-ami-ids', - 'hostname', 'block-device-mapping', 'kernel-id','placement/availability-zone', - 'instance-action', 'instance-id', 'instance-type', 'product-codes', - 'local-hostname', 'local-ipv4', 'public-hostname', 'public-ipv4', - 'ramdisk-id','reservation-id','security-groups', - 'public-keys/','public-keys/0/','public-keys/0/openssh-key','admin_pass'] +ec2nodes = [ + 'ami-id', 'ami-launch-index', 'ami-manifest-path', 'ancestor-ami-ids', + 'hostname', 'block-device-mapping', 'kernel-id', + 'placement/availability-zone', 'instance-action', 'instance-id', + 'instance-type', 'product-codes', 'local-hostname', 'local-ipv4', + 'public-hostname', 'public-ipv4', 'ramdisk-id', 'reservation-id', + 'security-groups', 'public-keys/', 'public-keys/0/', + 'public-keys/0/openssh-key', 'admin_pass'] CONF = cfg.CONF CONF.register_opts(opts) LOG = logging.getLogger(__name__) + class EC2Service(base.BaseMetadataService): def __init__(self): super(EC2Service, self).__init__() self._enable_retry = True self.error_count = 0 - def load(self): super(EC2Service, self).load() try: @@ -57,23 +59,23 @@ class EC2Service(base.BaseMetadataService): LOG.debug(err) LOG.debug(traceback.format_exc()) LOG.debug('Metadata not found at URL \'%s\'' % - CONF.ec2_metadata_base_url) + CONF.ec2_metadata_base_url) return False def _get_data(self, path): data = {} LOG.debug("Check for EC2 interface availability...") if not self._check_EC2(): - raise Exception("EC2 interface is not available") + raise Exception("EC2 interface is not available") LOG.debug('Getting data for the path: %s' % path) if path.endswith('meta_data.json'): for key in ec2nodes: LOG.debug('Getting metadata from: %s' % key) try: - data[key] = self._get_EC2_value(key) + data[key] = self._get_EC2_value(key) except: - LOG.info("EC2 value %s is not available. Skip it." % key) + LOG.info("EC2 value %s is not available. Skip it." % key) # Saving keys to the local folder self._load_public_keys(data) @@ -81,39 +83,41 @@ class EC2Service(base.BaseMetadataService): norm_path = posixpath.join(CONF.ec2_metadata_base_url, 'user-data') LOG.debug('Getting metadata from: %(norm_path)s' % locals()) try: - req = urllib2.Request(norm_path) - response = urllib2.urlopen(req) - data = response.read() - LOG.debug("Got data: %s" % data) + req = urllib2.Request(norm_path) + response = urllib2.urlopen(req) + data = response.read() + LOG.debug("Got data: %s" % data) except: - LOG.error("EC2 user-data is not available.") + LOG.error("EC2 user-data is not available.") return data def _check_EC2(self): try: - data = self._get_EC2_value('') - return True + data = self._get_EC2_value('') + return True except: - return False + return False def _get_EC2_value(self, key): - meta_path = posixpath.join(CONF.ec2_metadata_base_url, 'meta-data',key) - req = urllib2.Request(meta_path) - response = urllib2.urlopen(req) - return response.read() + meta_path = posixpath.join( + CONF.ec2_metadata_base_url, 'meta-data', key) + req = urllib2.Request(meta_path) + response = urllib2.urlopen(req) + return response.read() def _load_public_keys(self, data): - try: - key_list = self._get_EC2_value('public-keys/') - LOG.debug("Got a list of keys %s" % key_list) - data['public_keys'] = {} - - for key_name in key_list.split('\n'): - key_index = key_name.split('=')[0] - LOG.debug('Loading key %s' % key_index) - key = self._get_EC2_value('public-keys/%s/openssh-key' % key_index) - data['public_keys'].update({key_index : key}) - - except Exception, ex: - LOG.debug("Can't save public key %s" % ex) - LOG.debug(traceback.format_exc()) + try: + key_list = self._get_EC2_value('public-keys/') + LOG.debug("Got a list of keys %s" % key_list) + data['public_keys'] = {} + + for key_name in key_list.split('\n'): + key_index = key_name.split('=')[0] + LOG.debug('Loading key %s' % key_index) + key = self._get_EC2_value( + 'public-keys/%s/openssh-key' % key_index) + data['public_keys'].update({key_index: key}) + + except Exception, ex: + LOG.debug("Can't save public key %s" % ex) + LOG.debug(traceback.format_exc()) diff --git a/cloudbaseinit/metadata/services/httpservice.py b/cloudbaseinit/metadata/services/httpservice.py index 5609803c..93ae547b 100644 --- a/cloudbaseinit/metadata/services/httpservice.py +++ b/cloudbaseinit/metadata/services/httpservice.py @@ -23,14 +23,15 @@ from cloudbaseinit.openstack.common import log as logging opts = [ cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/', - help='The base URL where the service looks for metadata'), - ] + help='The base URL where the service looks for metadata'), +] CONF = cfg.CONF CONF.register_opts(opts) LOG = logging.getLogger(__name__) + class HttpService(base.BaseMetadataService): def __init__(self): super(HttpService, self).__init__() @@ -43,13 +44,13 @@ class HttpService(base.BaseMetadataService): return True except: LOG.debug('Metadata not found at URL \'%s\'' % - CONF.metadata_base_url) + CONF.metadata_base_url) return False @property def can_post_password(self): return True - + def _get_response(self, req): try: return urllib2.urlopen(req) @@ -83,5 +84,3 @@ class HttpService(base.BaseMetadataService): return False else: raise - - diff --git a/cloudbaseinit/osutils/base.py b/cloudbaseinit/osutils/base.py index 6f605cf4..f8148d6c 100644 --- a/cloudbaseinit/osutils/base.py +++ b/cloudbaseinit/osutils/base.py @@ -16,6 +16,7 @@ import subprocess + class BaseOSUtils(object): def reboot(self): pass @@ -25,9 +26,9 @@ class BaseOSUtils(object): def execute_process(self, args, shell=True): p = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=shell) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=shell) (out, err) = p.communicate() return (out, err, p.returncode) @@ -53,7 +54,8 @@ class BaseOSUtils(object): pass def set_static_network_config(self, adapter_name, address, netmask, - broadcast, gateway, dnsdomain, dnsnameservers): + broadcast, gateway, dnsdomain, + dnsnameservers): pass def set_config_value(self, name, value): @@ -61,4 +63,3 @@ class BaseOSUtils(object): def get_config_value(self, name): pass - diff --git a/cloudbaseinit/osutils/factory.py b/cloudbaseinit/osutils/factory.py index a5c84149..e623dc2d 100644 --- a/cloudbaseinit/osutils/factory.py +++ b/cloudbaseinit/osutils/factory.py @@ -18,12 +18,13 @@ import os from cloudbaseinit.utils import classloader + class OSUtilsFactory(object): def get_os_utils(self): osutils_class_paths = { - 'nt' : 'cloudbaseinit.osutils.windows.WindowsUtils', - 'posix' : 'cloudbaseinit.osutils.posix.PosixUtils' - } + 'nt': 'cloudbaseinit.osutils.windows.WindowsUtils', + 'posix': 'cloudbaseinit.osutils.posix.PosixUtils' + } cl = classloader.ClassLoader() return cl.load_class(osutils_class_paths[os.name])() diff --git a/cloudbaseinit/osutils/posix.py b/cloudbaseinit/osutils/posix.py index 8c11c82d..66c47eaa 100644 --- a/cloudbaseinit/osutils/posix.py +++ b/cloudbaseinit/osutils/posix.py @@ -16,8 +16,9 @@ import os -from cloudbaseinit.osutils.base import * +from cloudbaseinit.osutils import base -class PosixUtil(BaseOSUtils): + +class PosixUtil(base.BaseOSUtils): def reboot(self): os.system('reboot') diff --git a/cloudbaseinit/osutils/windows.py b/cloudbaseinit/osutils/windows.py index 03ad4c88..c80f7c16 100644 --- a/cloudbaseinit/osutils/windows.py +++ b/cloudbaseinit/osutils/windows.py @@ -84,15 +84,17 @@ class WindowsUtils(base.BaseOSUtils): def _get_user_wmi_object(self, username): conn = wmi.WMI(moniker='//./root/cimv2') username_san = self._sanitize_wmi_input(username) - q = conn.query('SELECT * FROM Win32_Account where name = \'%(username_san)s\'' % locals()) + q = conn.query('SELECT * FROM Win32_Account where name = ' + '\'%(username_san)s\'' % locals()) if len(q) > 0: return q[0] return None def user_exists(self, username): - return self._get_user_wmi_object(username) != None + return self._get_user_wmi_object(username) is not None - def _create_or_change_user(self, username, password, create, password_expires): + def _create_or_change_user(self, username, password, create, + password_expires): username_san = self.sanitize_shell_input(username) password_san = self.sanitize_shell_input(password) @@ -119,12 +121,12 @@ class WindowsUtils(base.BaseOSUtils): def create_user(self, username, password, password_expires=False): if not self._create_or_change_user(username, password, True, - password_expires): + password_expires): raise Exception("Create user failed") def set_user_password(self, username, password, password_expires=False): if not self._create_or_change_user(username, password, False, - password_expires): + password_expires): raise Exception("Set user password failed") def _get_user_sid_and_domain(self, username): @@ -135,10 +137,9 @@ class WindowsUtils(base.BaseOSUtils): ctypes.sizeof(domainName) / ctypes.sizeof(wintypes.WCHAR)) sidNameUse = wintypes.DWORD() - ret_val = advapi32.LookupAccountNameW(0, unicode(username), sid, - ctypes.byref(cbSid), domainName, - ctypes.byref(cchReferencedDomainName), - ctypes.byref(sidNameUse)) + ret_val = advapi32.LookupAccountNameW( + 0, unicode(username), sid, ctypes.byref(cbSid), domainName, + ctypes.byref(cchReferencedDomainName), ctypes.byref(sidNameUse)) if not ret_val: raise Exception("Cannot get user SID") @@ -150,7 +151,7 @@ class WindowsUtils(base.BaseOSUtils): lmi.lgrmi3_domainandname = unicode(username) ret_val = netapi32.NetLocalGroupAddMembers(0, unicode(groupname), 3, - ctypes.addressof(lmi), 1) + ctypes.addressof(lmi), 1) if ret_val == self.NERR_GroupNotFound: raise Exception('Group not found') @@ -172,10 +173,12 @@ class WindowsUtils(base.BaseOSUtils): return None return r.SID - def create_user_logon_session(self, username, password, domain='.', load_profile=True): + def create_user_logon_session(self, username, password, domain='.', + load_profile=True): token = wintypes.HANDLE() ret_val = advapi32.LogonUserW(unicode(username), unicode(domain), - unicode(password), 2, 0, ctypes.byref(token)) + unicode(password), 2, 0, + ctypes.byref(token)) if not ret_val: raise Exception("User logon failed") @@ -196,10 +199,10 @@ class WindowsUtils(base.BaseOSUtils): def get_user_home(self, username): user_sid = self.get_user_sid(username) if user_sid: - with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, - 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%s' - % user_sid) as key: - return _winreg.QueryValueEx(key, 'ProfileImagePath')[0] + with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\' + 'Microsoft\\Windows NT\\CurrentVersion\\' + 'ProfileList\\%s' % user_sid) as key: + return _winreg.QueryValueEx(key, 'ProfileImagePath')[0] LOG.debug('Home directory not found for user \'%s\'' % username) return None @@ -220,18 +223,18 @@ class WindowsUtils(base.BaseOSUtils): conn = wmi.WMI(moniker='//./root/cimv2') # Get Ethernet adapters only q = conn.query('SELECT * FROM Win32_NetworkAdapter WHERE ' - 'AdapterTypeId = 0 AND PhysicalAdapter = True') + 'AdapterTypeId = 0 AND PhysicalAdapter = True') for r in q: l.append(r.Name) return l def set_static_network_config(self, adapter_name, address, netmask, - broadcast, gateway, dnsnameservers): + broadcast, gateway, dnsnameservers): conn = wmi.WMI(moniker='//./root/cimv2') adapter_name_san = self._sanitize_wmi_input(adapter_name) q = conn.query('SELECT * FROM Win32_NetworkAdapter ' - 'where Name = \'%(adapter_name_san)s\'' % locals()) + 'where Name = \'%(adapter_name_san)s\'' % locals()) if not len(q): raise Exception("Network adapter not found") @@ -260,7 +263,7 @@ class WindowsUtils(base.BaseOSUtils): def set_config_value(self, name, value): with _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE, - self._config_key) as key: + self._config_key) as key: if type(value) == int: regtype = _winreg.REG_DWORD else: @@ -270,7 +273,7 @@ class WindowsUtils(base.BaseOSUtils): def get_config_value(self, name): try: with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, - self._config_key) as key: + self._config_key) as key: (value, regtype) = _winreg.QueryValueEx(key, name) return value except WindowsError: diff --git a/cloudbaseinit/plugins/base.py b/cloudbaseinit/plugins/base.py index 0583d5e2..dcc7eb65 100644 --- a/cloudbaseinit/plugins/base.py +++ b/cloudbaseinit/plugins/base.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. + class BasePlugin(object): def execute(self, service): pass diff --git a/cloudbaseinit/plugins/factory.py b/cloudbaseinit/plugins/factory.py index a588acf6..150971b4 100644 --- a/cloudbaseinit/plugins/factory.py +++ b/cloudbaseinit/plugins/factory.py @@ -18,17 +18,19 @@ from cloudbaseinit.openstack.common import cfg from cloudbaseinit.utils import classloader opts = [ - cfg.ListOpt('plugins', default=[ + cfg.ListOpt( + 'plugins', + default=[ 'cloudbaseinit.plugins.windows.sethostname.SetHostNamePlugin', 'cloudbaseinit.plugins.windows.createuser.CreateUserPlugin', 'cloudbaseinit.plugins.windows.networkconfig.NetworkConfigPlugin', 'cloudbaseinit.plugins.windows.sshpublickeys.' - 'SetUserSSHPublicKeysPlugin', + 'SetUserSSHPublicKeysPlugin', 'cloudbaseinit.plugins.windows.userdata.UserDataPlugin' ], help='List of enabled plugin classes, ' - 'to executed in the provided order'), - ] + 'to executed in the provided order'), +] CONF = cfg.CONF CONF.register_opts(opts) diff --git a/cloudbaseinit/plugins/windows/createuser.py b/cloudbaseinit/plugins/windows/createuser.py index 3df98790..256749fe 100644 --- a/cloudbaseinit/plugins/windows/createuser.py +++ b/cloudbaseinit/plugins/windows/createuser.py @@ -25,15 +25,15 @@ from cloudbaseinit.plugins import base from cloudbaseinit.utils import crypt opts = [ - cfg.StrOpt('username', default='Admin', - help='User to be added to the system or updated if already existing'), - cfg.ListOpt('groups', default=['Administrators'], - help='List of local groups to which the user specified ' - 'in \'username\' will be added'), - cfg.BoolOpt('inject_user_password', default=True, - help='Set the password provided in the configuration. ' - 'If False or no password is provided, a random one will be set'), - ] + cfg.StrOpt('username', default='Admin', help='User to be added to the ' + 'system or updated if already existing'), + cfg.ListOpt('groups', default=['Administrators'], help='List of local ' + 'groups to which the user specified in \'username\' will ' + 'be added'), + cfg.BoolOpt('inject_user_password', default=True, help='Set the password ' + 'provided in the configuration. If False or no password is ' + 'provided, a random one will be set'), +] CONF = cfg.CONF CONF.register_opts(opts) diff --git a/cloudbaseinit/plugins/windows/networkconfig.py b/cloudbaseinit/plugins/windows/networkconfig.py index a7e2eb67..4c69a06b 100644 --- a/cloudbaseinit/plugins/windows/networkconfig.py +++ b/cloudbaseinit/plugins/windows/networkconfig.py @@ -18,22 +18,22 @@ import re from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import log as logging -from cloudbaseinit.osutils.factory import * -from cloudbaseinit.plugins.base import * +from cloudbaseinit.osutils import factory as osutils_factory +from cloudbaseinit.plugins import base LOG = logging.getLogger(__name__) opts = [ - cfg.StrOpt('network_adapter', default=None, - help='Network adapter to configure. If not specified, the first ' - 'available ethernet adapter will be chosen'), - ] + cfg.StrOpt('network_adapter', default=None, help='Network adapter to ' + 'configure. If not specified, the first available ethernet ' + 'adapter will be chosen'), +] CONF = cfg.CONF CONF.register_opts(opts) -class NetworkConfigPlugin(): +class NetworkConfigPlugin(base.BasePlugin): def execute(self, service): meta_data = service.get_meta_data('openstack') if 'network_config' not in meta_data: @@ -50,11 +50,12 @@ class NetworkConfigPlugin(): # TODO (alexpilotti): implement a proper grammar m = re.search(r'iface eth0 inet static\s+' - 'address\s+(?P
[^\s]+)\s+' - 'netmask\s+(?P[^\s]+)\s+' - 'broadcast\s+(?P[^\s]+)\s+' - 'gateway\s+(?P[^\s]+)\s+' - 'dns\-nameservers\s+(?P[^\r\n]+)\s+', debian_network_conf) + r'address\s+(?P
[^\s]+)\s+' + r'netmask\s+(?P[^\s]+)\s+' + r'broadcast\s+(?P[^\s]+)\s+' + r'gateway\s+(?P[^\s]+)\s+' + r'dns\-nameservers\s+(?P[^\r\n]+)\s+', + debian_network_conf) if not m: raise Exception("network_config format not recognized") @@ -64,7 +65,7 @@ class NetworkConfigPlugin(): gateway = m.group('gateway') dnsnameservers = m.group('dnsnameservers').strip().split(' ') - osutils = OSUtilsFactory().get_os_utils() + osutils = osutils_factory.OSUtilsFactory().get_os_utils() network_adapter_name = CONF.network_adapter if not network_adapter_name: diff --git a/cloudbaseinit/plugins/windows/sethostname.py b/cloudbaseinit/plugins/windows/sethostname.py index aeaa0413..92a92c1f 100644 --- a/cloudbaseinit/plugins/windows/sethostname.py +++ b/cloudbaseinit/plugins/windows/sethostname.py @@ -14,22 +14,21 @@ # License for the specific language governing permissions and limitations # under the License. -from cloudbaseinit.osutils.factory import * -from cloudbaseinit.plugins.base import * +from cloudbaseinit.osutils import factory as osutils_factory +from cloudbaseinit.plugins import base from cloudbaseinit.openstack.common import log as logging LOG = logging.getLogger(__name__) -class SetHostNamePlugin(BasePlugin): +class SetHostNamePlugin(base.BasePlugin): def execute(self, service): meta_data = service.get_meta_data('openstack') if 'hostname' not in meta_data: LOG.debug('Hostname not found in metadata') return False - osutils = OSUtilsFactory().get_os_utils() + osutils = osutils_factory.OSUtilsFactory().get_os_utils() new_host_name = meta_data['hostname'].split('.', 1)[0] return osutils.set_host_name(new_host_name) - diff --git a/cloudbaseinit/plugins/windows/sshpublickeys.py b/cloudbaseinit/plugins/windows/sshpublickeys.py index e28b7939..84a4b9b9 100644 --- a/cloudbaseinit/plugins/windows/sshpublickeys.py +++ b/cloudbaseinit/plugins/windows/sshpublickeys.py @@ -18,14 +18,14 @@ import os from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import log as logging -from cloudbaseinit.osutils.factory import * -from cloudbaseinit.plugins.base import * +from cloudbaseinit.osutils import factory as osutils_factory +from cloudbaseinit.plugins import base CONF = cfg.CONF LOG = logging.getLogger(__name__) -class SetUserSSHPublicKeysPlugin(BasePlugin): +class SetUserSSHPublicKeysPlugin(base.BasePlugin): def execute(self, service): meta_data = service.get_meta_data('openstack') if not 'public_keys' in meta_data: @@ -33,7 +33,7 @@ class SetUserSSHPublicKeysPlugin(BasePlugin): username = CONF.username - osutils = OSUtilsFactory().get_os_utils() + osutils = osutils_factory.OSUtilsFactory().get_os_utils() user_home = osutils.get_user_home(username) if not user_home: diff --git a/cloudbaseinit/plugins/windows/userdata.py b/cloudbaseinit/plugins/windows/userdata.py index d209b05b..595d46bd 100644 --- a/cloudbaseinit/plugins/windows/userdata.py +++ b/cloudbaseinit/plugins/windows/userdata.py @@ -14,18 +14,19 @@ # License for the specific language governing permissions and limitations # under the License. +import os import re import tempfile import uuid from cloudbaseinit.openstack.common import log as logging -from cloudbaseinit.osutils.factory import * -from cloudbaseinit.plugins.base import * +from cloudbaseinit.osutils import factory as osutils_factory +from cloudbaseinit.plugins import base LOG = logging.getLogger(__name__) -class UserDataPlugin(): +class UserDataPlugin(base.BasePlugin): def execute(self, service): user_data = service.get_user_data('openstack') if not user_data: @@ -33,7 +34,7 @@ class UserDataPlugin(): LOG.debug('User data content:\n%s' % user_data) - osutils = OSUtilsFactory().get_os_utils() + osutils = osutils_factory.OSUtilsFactory().get_os_utils() target_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4())) if re.search(r'^rem cmd\s', user_data, re.I): @@ -63,10 +64,10 @@ class UserDataPlugin(): LOG.debug('User_data stdout:\n%s' % out) LOG.debug('User_data stderr:\n%s' % err) except Exception, ex: - LOG.warning('An error occurred during user_data execution: \'%s\'' % ex) + LOG.warning('An error occurred during user_data execution: \'%s\'' + % ex) finally: if os.path.exists(target_path): os.remove(target_path) return False - diff --git a/cloudbaseinit/shell.py b/cloudbaseinit/shell.py index f77c340d..da099e84 100644 --- a/cloudbaseinit/shell.py +++ b/cloudbaseinit/shell.py @@ -16,9 +16,9 @@ import sys +from cloudbaseinit import init from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import log as logging2 -from cloudbaseinit.init import * CONF = cfg.CONF LOG = logging2.getLogger(__name__) @@ -28,7 +28,4 @@ def main(): CONF(sys.argv[1:]) logging2.setup('cloudbaseinit') - init = InitManager() - init.configure_host() - - + init.InitManager().configure_host() diff --git a/cloudbaseinit/utils/crypt.py b/cloudbaseinit/utils/crypt.py index c2d8552b..96b1d3aa 100644 --- a/cloudbaseinit/utils/crypt.py +++ b/cloudbaseinit/utils/crypt.py @@ -28,6 +28,7 @@ else: openssl = ctypes.CDLL(openssl_lib_path) clib = ctypes.CDLL(ctypes.util.find_library("c")) + class RSA(ctypes.Structure): _fields_ = [ ("pad", ctypes.c_int), diff --git a/setup.py b/setup.py index d5a1e3e9..d8b212d7 100644 --- a/setup.py +++ b/setup.py @@ -22,26 +22,26 @@ requires = common_setup.parse_requirements() dependency_links = common_setup.parse_dependency_links() setuptools.setup(name='cloudbase-init', - version='0.9.0', - description='Portable cloud initialization service', - author='Cloudbase Solutions Srl', - author_email='apilotti@cloudbasesolutions.com', - url='http://www.cloudbase.it/', - classifiers=[ - 'Environment :: OpenStack', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - ], - cmdclass=common_setup.get_cmdclass(), - packages=setuptools.find_packages(exclude=['bin']), - install_requires=requires, - dependency_links=dependency_links, - include_package_data=True, - setup_requires=['setuptools_git>=0.4'], - entry_points={'console_scripts': ['cloudbase-init = cloudbaseinit.shell:main']}, - py_modules=[]) + version='0.9.0', + description='Portable cloud initialization service', + author='Cloudbase Solutions Srl', + author_email='apilotti@cloudbasesolutions.com', + url='http://www.cloudbase.it/', + classifiers=['Environment :: OpenStack', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software ' + 'License', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7'], + cmdclass=common_setup.get_cmdclass(), + packages=setuptools.find_packages(exclude=['bin']), + install_requires=requires, + dependency_links=dependency_links, + include_package_data=True, + setup_requires=['setuptools_git>=0.4'], + entry_points={'console_scripts': + ['cloudbase-init = cloudbaseinit.shell:main']}, + py_modules=[])