pylint and pep8

This commit is contained in:
Alessandro Pilotti 2013-03-28 23:57:20 +02:00
parent 6debb9d40e
commit fcd8271c5b
23 changed files with 244 additions and 224 deletions

View File

@ -14,16 +14,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import sys from cloudbaseinit.metadata import factory as metadata_factory
from cloudbaseinit.metadata.factory import *
from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.osutils.factory import * from cloudbaseinit.osutils import factory as osutils_factory
from cloudbaseinit.plugins.factory import * from cloudbaseinit.plugins import factory as plugins_factory
from cloudbaseinit.utils import *
CONF = cfg.CONF
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -35,18 +30,19 @@ class InitManager(object):
def _mark_as_configured(self, osutils): def _mark_as_configured(self, osutils):
osutils.set_config_value(self._config_done_key, 1) osutils.set_config_value(self._config_done_key, 1)
def configure_host(self): def configure_host(self):
osutils = OSUtilsFactory().get_os_utils() osutils = osutils_factory.OSUtilsFactory().get_os_utils()
if self._is_already_configured(osutils): if self._is_already_configured(osutils):
LOG.info('Host already configured, skipping configuration') LOG.info('Host already configured, skipping configuration')
return return
plugins = PluginFactory().load_plugins() plugins = plugins_factory.PluginFactory().load_plugins()
service = MetadataServiceFactory().get_metadata_service() mdsf = metadata_factory.MetadataServiceFactory()
service = mdsf.get_metadata_service()
LOG.info('Metadata service loaded: \'%s\'' % LOG.info('Metadata service loaded: \'%s\'' %
service.__class__.__name__) service.__class__.__name__)
reboot_required = False reboot_required = False
try: try:
@ -59,12 +55,12 @@ class InitManager(object):
reboot_required = True reboot_required = True
except Exception, ex: except Exception, ex:
LOG.error('plugin \'%(plugin_name)s\' failed ' LOG.error('plugin \'%(plugin_name)s\' failed '
'with error \'%(ex)s\'' % locals()) 'with error \'%(ex)s\'' % locals())
finally: finally:
service.cleanup() service.cleanup()
self._mark_as_configured(osutils) self._mark_as_configured(osutils)
if reboot_required: if reboot_required:
try: try:
osutils.reboot() osutils.reboot()

View File

@ -19,16 +19,18 @@ from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.utils import classloader from cloudbaseinit.utils import classloader
opts = [ opts = [
cfg.ListOpt('metadata_services', default=[ cfg.ListOpt('metadata_services',
'cloudbaseinit.metadata.services.httpservice.HttpService', default=[
'cloudbaseinit.metadata.services.configdrive.configdrive.' 'cloudbaseinit.metadata.services.httpservice.HttpService',
'ConfigDriveService', 'cloudbaseinit.metadata.services.configdrive.configdrive.'
'cloudbaseinit.metadata.services.ec2service.EC2Service' 'ConfigDriveService',
], 'cloudbaseinit.metadata.services.ec2service.EC2Service'
help='List of enabled metadata service classes, ' ],
'to be tested fro availability in the provided order. ' help='List of enabled metadata service classes, '
'The first available service will be used to retrieve metadata') 'to be tested fro availability in the provided order. '
] 'The first available service will be used to retrieve '
'metadata')
]
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)
@ -46,6 +48,5 @@ class MetadataServiceFactory(object):
return service return service
except Exception, ex: except Exception, ex:
LOG.error('Failed to load metadata service \'%(class_path)s\' ' LOG.error('Failed to load metadata service \'%(class_path)s\' '
'with error: %(ex)s'% 'with error: %(ex)s' % locals())
locals())
raise Exception("No available service found") raise Exception("No available service found")

View File

@ -24,12 +24,12 @@ from cloudbaseinit.openstack.common import log as logging
opts = [ opts = [
cfg.IntOpt('retry_count', default=5, cfg.IntOpt('retry_count', default=5,
help='Max. number of attempts for fetching metadata in ' help='Max. number of attempts for fetching metadata in '
'case of transient errors'), 'case of transient errors'),
cfg.FloatOpt('retry_count_interval', default=4, cfg.FloatOpt('retry_count_interval', default=4,
help='Interval between attempts in case of transient errors, ' help='Interval between attempts in case of transient errors, '
'expressed in seconds'), 'expressed in seconds'),
] ]
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)

View File

@ -14,23 +14,22 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import json
import os import os
import shutil import shutil
import tempfile import tempfile
import uuid 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 cfg
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
from manager import * from cloudbaseinit.metadata.services.configdrive import manager
opts = [ opts = [
cfg.BoolOpt('config_drive_raw_hhd', default=True, 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, 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 = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)
@ -38,7 +37,7 @@ CONF.register_opts(opts)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class ConfigDriveService(BaseMetadataService): class ConfigDriveService(base.BaseMetadataService):
def __init__(self): def __init__(self):
self._metadata_path = None self._metadata_path = None
@ -47,12 +46,14 @@ class ConfigDriveService(BaseMetadataService):
target_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4())) target_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))
mgr = ConfigDriveManager() mgr = manager.ConfigDriveManager()
found = mgr.get_config_drive_files(target_path, 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: if found:
self._metadata_path = target_path 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 return found
def _get_data(self, path): def _get_data(self, path):

View File

@ -26,8 +26,10 @@ from ctypes import wintypes
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
from windows.disk import physical_disk from cloudbaseinit.metadata.services.configdrive.windows.disk \
from windows.disk import virtual_disk import physical_disk
from cloudbaseinit.metadata.services.configdrive.windows.disk \
import virtual_disk
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -38,41 +40,45 @@ class ConfigDriveManager(object):
conn = wmi.WMI(moniker='//./root/cimv2') conn = wmi.WMI(moniker='//./root/cimv2')
q = conn.query('SELECT DeviceID FROM Win32_DiskDrive') q = conn.query('SELECT DeviceID FROM Win32_DiskDrive')
for r in q: for r in q:
l.append(r.DeviceID) l.append(r.DeviceID)
return l return l
def _get_config_drive_cdrom_mount_point(self): def _get_config_drive_cdrom_mount_point(self):
conn = wmi.WMI(moniker='//./root/cimv2') 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: for r in q:
drive = r.Drive + '\\' 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: for r1 in q1:
if r1.Label == "config-2" and \ 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 drive
return None return None
def _c_char_array_to_c_ushort(self, buf, offset): def _c_char_array_to_c_ushort(self, buf, offset):
low = ctypes.cast(buf[offset], low = ctypes.cast(buf[offset],
ctypes.POINTER(wintypes.WORD)).contents ctypes.POINTER(wintypes.WORD)).contents
high = ctypes.cast(buf[offset + 1], high = ctypes.cast(buf[offset + 1],
ctypes.POINTER(wintypes.WORD)).contents ctypes.POINTER(wintypes.WORD)).contents
return (high.value << 8) + low.value return (high.value << 8) + low.value
def _get_iso_disk_size(self, phys_disk): def _get_iso_disk_size(self, phys_disk):
geom = phys_disk.get_geometry() geom = phys_disk.get_geometry()
if geom.MediaType != Win32_DiskGeometry.FixedMedia: if geom.MediaType != physical_disk.Win32_DiskGeometry.FixedMedia:
return None return None
disk_size = geom.Cylinders * geom.TracksPerCylinder * \ disk_size = geom.Cylinders * geom.TracksPerCylinder * \
geom.SectorsPerTrack * geom.BytesPerSector geom.SectorsPerTrack * geom.BytesPerSector
boot_record_off = 0x8000; boot_record_off = 0x8000
id_off = 1; id_off = 1
volume_size_off = 80; volume_size_off = 80
block_size_off = 128; block_size_off = 128
iso_id = 'CD001' iso_id = 'CD001'
offset = boot_record_off / geom.BytesPerSector * geom.BytesPerSector 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, bytes_read) = phys_disk.read(bytes_to_read)
buf_off = boot_record_off - offset + id_off 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 return None
buf_off = boot_record_off - offset + volume_size_off 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) iso_file_size = self._get_iso_disk_size(phys_disk)
if iso_file_size: if iso_file_size:
self._write_iso_file(phys_disk, iso_file_path, self._write_iso_file(phys_disk, iso_file_path,
iso_file_size) iso_file_size)
iso_disk_found = True iso_disk_found = True
break break
except: except:
@ -148,14 +154,15 @@ class ConfigDriveManager(object):
def _os_supports_iso_virtual_disks(self): def _os_supports_iso_virtual_disks(self):
# Feature supported starting from Windows 8 / 2012 # Feature supported starting from Windows 8 / 2012
ver = sys.getwindowsversion(); ver = sys.getwindowsversion()
supported = (ver[0] >= 6 and ver[1] >= 2) supported = (ver[0] >= 6 and ver[1] >= 2)
if not supported: if not supported:
LOG.debug('ISO virtual disks are not supported on ' LOG.debug('ISO virtual disks are not supported on '
'this version of Windows') 'this version of Windows')
return supported 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 config_drive_found = False
if check_raw_hhd and self._os_supports_iso_virtual_disks(): if check_raw_hhd and self._os_supports_iso_virtual_disks():
LOG.debug('Looking for Config Drive in raw HDDs') 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): def _get_conf_drive_from_raw_hdd(self, target_path):
config_drive_found = False config_drive_found = False
iso_file_path = os.path.join(tempfile.gettempdir(), iso_file_path = os.path.join(tempfile.gettempdir(),
str(uuid.uuid4()) + '.iso') str(uuid.uuid4()) + '.iso')
try: try:
if self._extract_iso_disk_file(iso_file_path): if self._extract_iso_disk_file(iso_file_path):
self._copy_iso_files(iso_file_path, target_path) self._copy_iso_files(iso_file_path, target_path)
@ -187,4 +194,3 @@ class ConfigDriveManager(object):
if os.path.exists(iso_file_path): if os.path.exists(iso_file_path):
os.remove(iso_file_path) os.remove(iso_file_path)
return config_drive_found return config_drive_found

View File

@ -93,7 +93,8 @@ class PhysicalDisk(object):
low = wintypes.DWORD(offset & 0xFFFFFFFFL) low = wintypes.DWORD(offset & 0xFFFFFFFFL)
ret_val = kernel32.SetFilePointer(self._handle, low, 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: if ret_val == self.INVALID_SET_FILE_POINTER:
raise Exception("Seek error") raise Exception("Seek error")
@ -101,7 +102,7 @@ class PhysicalDisk(object):
buf = ctypes.create_string_buffer(bytes_to_read) buf = ctypes.create_string_buffer(bytes_to_read)
bytes_read = wintypes.DWORD() bytes_read = wintypes.DWORD()
ret_val = kernel32.ReadFile(self._handle, buf, bytes_to_read, ret_val = kernel32.ReadFile(self._handle, buf, bytes_to_read,
ctypes.byref(bytes_read), 0) ctypes.byref(bytes_read), 0)
if not ret_val: if not ret_val:
raise Exception("Read exception") raise Exception("Read exception")
return (buf, bytes_read.value) return (buf, bytes_read.value)

View File

@ -36,7 +36,7 @@ def get_WIN32_VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT():
guid.Data1 = 0xec984aec guid.Data1 = 0xec984aec
guid.Data2 = 0xa0f9 guid.Data2 = 0xa0f9
guid.Data3 = 0x47e9 guid.Data3 = 0x47e9
ByteArray8 = wintypes.BYTE * 8; ByteArray8 = wintypes.BYTE * 8
guid.Data4 = ByteArray8(0x90, 0x1f, 0x71, 0x41, 0x5a, 0x66, 0x34, 0x5b) guid.Data4 = ByteArray8(0x90, 0x1f, 0x71, 0x41, 0x5a, 0x66, 0x34, 0x5b)
return guid return guid
@ -77,31 +77,34 @@ class VirtualDisk(object):
vst.VendorId = get_WIN32_VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT() vst.VendorId = get_WIN32_VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT()
handle = wintypes.HANDLE() handle = wintypes.HANDLE()
ret_val = virtdisk.OpenVirtualDisk(ctypes.byref(vst), ctypes.c_wchar_p(self._path), ret_val = virtdisk.OpenVirtualDisk(ctypes.byref(vst),
self.VIRTUAL_DISK_ACCESS_ATTACH_RO | self.VIRTUAL_DISK_ACCESS_READ, ctypes.c_wchar_p(self._path),
self.OPEN_VIRTUAL_DISK_FLAG_NONE, 0, ctypes.byref(handle)) self.VIRTUAL_DISK_ACCESS_ATTACH_RO |
self.VIRTUAL_DISK_ACCESS_READ,
self.OPEN_VIRTUAL_DISK_FLAG_NONE, 0,
ctypes.byref(handle))
if ret_val: if ret_val:
raise Exception("Cannot open virtual disk") raise Exception("Cannot open virtual disk")
self._handle = handle self._handle = handle
def attach(self): def attach(self):
ret_val = virtdisk.AttachVirtualDisk(self._handle, 0, ret_val = virtdisk.AttachVirtualDisk(
self.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, self._handle, 0, self.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, 0, 0, 0)
0, 0, 0)
if ret_val: if ret_val:
raise Exception("Cannot attach virtual disk") raise Exception("Cannot attach virtual disk")
def detach(self): def detach(self):
ret_val = virtdisk.DetachVirtualDisk(self._handle, ret_val = virtdisk.DetachVirtualDisk(
self.DETACH_VIRTUAL_DISK_FLAG_NONE, 0) self._handle, self.DETACH_VIRTUAL_DISK_FLAG_NONE, 0)
if ret_val: if ret_val:
raise Exception("Cannot detach virtual disk") raise Exception("Cannot detach virtual disk")
def get_physical_path(self): def get_physical_path(self):
buf = ctypes.create_unicode_buffer(1024) buf = ctypes.create_unicode_buffer(1024)
bufLen = wintypes.DWORD(ctypes.sizeof(buf)); bufLen = wintypes.DWORD(ctypes.sizeof(buf))
ret_val = virtdisk.GetVirtualDiskPhysicalPath(self._handle, ret_val = virtdisk.GetVirtualDiskPhysicalPath(self._handle,
ctypes.byref(bufLen), buf) ctypes.byref(bufLen),
buf)
if ret_val: if ret_val:
raise Exception("Cannot get virtual disk physical path") raise Exception("Cannot get virtual disk physical path")
return buf.value return buf.value
@ -120,12 +123,13 @@ class VirtualDisk(object):
i = 0 i = 0
while not mount_point and i < buf_len: while not mount_point and i < buf_len:
curr_drive = ctypes.wstring_at(ctypes.addressof(buf) + \ curr_drive = ctypes.wstring_at(ctypes.addressof(buf) + i *
i * ctypes.sizeof(wintypes.WCHAR))[:-1] ctypes.sizeof(wintypes.WCHAR))[:-1]
dev = ctypes.create_unicode_buffer(2048) dev = ctypes.create_unicode_buffer(2048)
ret_val = kernel32.QueryDosDeviceW(curr_drive, dev, 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: if not ret_val:
raise Exception("Cannot query NT device") raise Exception("Cannot query NT device")

View File

@ -27,27 +27,29 @@ opts = [
cfg.StrOpt('ec2_metadata_base_url', cfg.StrOpt('ec2_metadata_base_url',
default='http://169.254.169.254/2009-04-04/', default='http://169.254.169.254/2009-04-04/',
help='The base URL where the service looks for metadata'), help='The base URL where the service looks for metadata'),
] ]
ec2nodes = ['ami-id', 'ami-launch-index', 'ami-manifest-path', 'ancestor-ami-ids', ec2nodes = [
'hostname', 'block-device-mapping', 'kernel-id','placement/availability-zone', 'ami-id', 'ami-launch-index', 'ami-manifest-path', 'ancestor-ami-ids',
'instance-action', 'instance-id', 'instance-type', 'product-codes', 'hostname', 'block-device-mapping', 'kernel-id',
'local-hostname', 'local-ipv4', 'public-hostname', 'public-ipv4', 'placement/availability-zone', 'instance-action', 'instance-id',
'ramdisk-id','reservation-id','security-groups', 'instance-type', 'product-codes', 'local-hostname', 'local-ipv4',
'public-keys/','public-keys/0/','public-keys/0/openssh-key','admin_pass'] '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 = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class EC2Service(base.BaseMetadataService): class EC2Service(base.BaseMetadataService):
def __init__(self): def __init__(self):
super(EC2Service, self).__init__() super(EC2Service, self).__init__()
self._enable_retry = True self._enable_retry = True
self.error_count = 0 self.error_count = 0
def load(self): def load(self):
super(EC2Service, self).load() super(EC2Service, self).load()
try: try:
@ -57,23 +59,23 @@ class EC2Service(base.BaseMetadataService):
LOG.debug(err) LOG.debug(err)
LOG.debug(traceback.format_exc()) LOG.debug(traceback.format_exc())
LOG.debug('Metadata not found at URL \'%s\'' % LOG.debug('Metadata not found at URL \'%s\'' %
CONF.ec2_metadata_base_url) CONF.ec2_metadata_base_url)
return False return False
def _get_data(self, path): def _get_data(self, path):
data = {} data = {}
LOG.debug("Check for EC2 interface availability...") LOG.debug("Check for EC2 interface availability...")
if not self._check_EC2(): 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) LOG.debug('Getting data for the path: %s' % path)
if path.endswith('meta_data.json'): if path.endswith('meta_data.json'):
for key in ec2nodes: for key in ec2nodes:
LOG.debug('Getting metadata from: %s' % key) LOG.debug('Getting metadata from: %s' % key)
try: try:
data[key] = self._get_EC2_value(key) data[key] = self._get_EC2_value(key)
except: 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 # Saving keys to the local folder
self._load_public_keys(data) self._load_public_keys(data)
@ -81,39 +83,41 @@ class EC2Service(base.BaseMetadataService):
norm_path = posixpath.join(CONF.ec2_metadata_base_url, 'user-data') norm_path = posixpath.join(CONF.ec2_metadata_base_url, 'user-data')
LOG.debug('Getting metadata from: %(norm_path)s' % locals()) LOG.debug('Getting metadata from: %(norm_path)s' % locals())
try: try:
req = urllib2.Request(norm_path) req = urllib2.Request(norm_path)
response = urllib2.urlopen(req) response = urllib2.urlopen(req)
data = response.read() data = response.read()
LOG.debug("Got data: %s" % data) LOG.debug("Got data: %s" % data)
except: except:
LOG.error("EC2 user-data is not available.") LOG.error("EC2 user-data is not available.")
return data return data
def _check_EC2(self): def _check_EC2(self):
try: try:
data = self._get_EC2_value('') data = self._get_EC2_value('')
return True return True
except: except:
return False return False
def _get_EC2_value(self, key): def _get_EC2_value(self, key):
meta_path = posixpath.join(CONF.ec2_metadata_base_url, 'meta-data',key) meta_path = posixpath.join(
req = urllib2.Request(meta_path) CONF.ec2_metadata_base_url, 'meta-data', key)
response = urllib2.urlopen(req) req = urllib2.Request(meta_path)
return response.read() response = urllib2.urlopen(req)
return response.read()
def _load_public_keys(self, data): def _load_public_keys(self, data):
try: try:
key_list = self._get_EC2_value('public-keys/') key_list = self._get_EC2_value('public-keys/')
LOG.debug("Got a list of keys %s" % key_list) LOG.debug("Got a list of keys %s" % key_list)
data['public_keys'] = {} data['public_keys'] = {}
for key_name in key_list.split('\n'): for key_name in key_list.split('\n'):
key_index = key_name.split('=')[0] key_index = key_name.split('=')[0]
LOG.debug('Loading key %s' % key_index) LOG.debug('Loading key %s' % key_index)
key = self._get_EC2_value('public-keys/%s/openssh-key' % key_index) key = self._get_EC2_value(
data['public_keys'].update({key_index : key}) '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) except Exception, ex:
LOG.debug(traceback.format_exc()) LOG.debug("Can't save public key %s" % ex)
LOG.debug(traceback.format_exc())

View File

@ -23,14 +23,15 @@ from cloudbaseinit.openstack.common import log as logging
opts = [ opts = [
cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/', 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 = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class HttpService(base.BaseMetadataService): class HttpService(base.BaseMetadataService):
def __init__(self): def __init__(self):
super(HttpService, self).__init__() super(HttpService, self).__init__()
@ -43,13 +44,13 @@ class HttpService(base.BaseMetadataService):
return True return True
except: except:
LOG.debug('Metadata not found at URL \'%s\'' % LOG.debug('Metadata not found at URL \'%s\'' %
CONF.metadata_base_url) CONF.metadata_base_url)
return False return False
@property @property
def can_post_password(self): def can_post_password(self):
return True return True
def _get_response(self, req): def _get_response(self, req):
try: try:
return urllib2.urlopen(req) return urllib2.urlopen(req)
@ -83,5 +84,3 @@ class HttpService(base.BaseMetadataService):
return False return False
else: else:
raise raise

View File

@ -16,6 +16,7 @@
import subprocess import subprocess
class BaseOSUtils(object): class BaseOSUtils(object):
def reboot(self): def reboot(self):
pass pass
@ -25,9 +26,9 @@ class BaseOSUtils(object):
def execute_process(self, args, shell=True): def execute_process(self, args, shell=True):
p = subprocess.Popen(args, p = subprocess.Popen(args,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
shell=shell) shell=shell)
(out, err) = p.communicate() (out, err) = p.communicate()
return (out, err, p.returncode) return (out, err, p.returncode)
@ -53,7 +54,8 @@ class BaseOSUtils(object):
pass pass
def set_static_network_config(self, adapter_name, address, netmask, def set_static_network_config(self, adapter_name, address, netmask,
broadcast, gateway, dnsdomain, dnsnameservers): broadcast, gateway, dnsdomain,
dnsnameservers):
pass pass
def set_config_value(self, name, value): def set_config_value(self, name, value):
@ -61,4 +63,3 @@ class BaseOSUtils(object):
def get_config_value(self, name): def get_config_value(self, name):
pass pass

View File

@ -18,12 +18,13 @@ import os
from cloudbaseinit.utils import classloader from cloudbaseinit.utils import classloader
class OSUtilsFactory(object): class OSUtilsFactory(object):
def get_os_utils(self): def get_os_utils(self):
osutils_class_paths = { osutils_class_paths = {
'nt' : 'cloudbaseinit.osutils.windows.WindowsUtils', 'nt': 'cloudbaseinit.osutils.windows.WindowsUtils',
'posix' : 'cloudbaseinit.osutils.posix.PosixUtils' 'posix': 'cloudbaseinit.osutils.posix.PosixUtils'
} }
cl = classloader.ClassLoader() cl = classloader.ClassLoader()
return cl.load_class(osutils_class_paths[os.name])() return cl.load_class(osutils_class_paths[os.name])()

View File

@ -16,8 +16,9 @@
import os import os
from cloudbaseinit.osutils.base import * from cloudbaseinit.osutils import base
class PosixUtil(BaseOSUtils):
class PosixUtil(base.BaseOSUtils):
def reboot(self): def reboot(self):
os.system('reboot') os.system('reboot')

View File

@ -84,15 +84,17 @@ class WindowsUtils(base.BaseOSUtils):
def _get_user_wmi_object(self, username): def _get_user_wmi_object(self, username):
conn = wmi.WMI(moniker='//./root/cimv2') conn = wmi.WMI(moniker='//./root/cimv2')
username_san = self._sanitize_wmi_input(username) 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: if len(q) > 0:
return q[0] return q[0]
return None return None
def user_exists(self, username): 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) username_san = self.sanitize_shell_input(username)
password_san = self.sanitize_shell_input(password) password_san = self.sanitize_shell_input(password)
@ -119,12 +121,12 @@ class WindowsUtils(base.BaseOSUtils):
def create_user(self, username, password, password_expires=False): def create_user(self, username, password, password_expires=False):
if not self._create_or_change_user(username, password, True, if not self._create_or_change_user(username, password, True,
password_expires): password_expires):
raise Exception("Create user failed") raise Exception("Create user failed")
def set_user_password(self, username, password, password_expires=False): def set_user_password(self, username, password, password_expires=False):
if not self._create_or_change_user(username, password, False, if not self._create_or_change_user(username, password, False,
password_expires): password_expires):
raise Exception("Set user password failed") raise Exception("Set user password failed")
def _get_user_sid_and_domain(self, username): def _get_user_sid_and_domain(self, username):
@ -135,10 +137,9 @@ class WindowsUtils(base.BaseOSUtils):
ctypes.sizeof(domainName) / ctypes.sizeof(wintypes.WCHAR)) ctypes.sizeof(domainName) / ctypes.sizeof(wintypes.WCHAR))
sidNameUse = wintypes.DWORD() sidNameUse = wintypes.DWORD()
ret_val = advapi32.LookupAccountNameW(0, unicode(username), sid, ret_val = advapi32.LookupAccountNameW(
ctypes.byref(cbSid), domainName, 0, unicode(username), sid, ctypes.byref(cbSid), domainName,
ctypes.byref(cchReferencedDomainName), ctypes.byref(cchReferencedDomainName), ctypes.byref(sidNameUse))
ctypes.byref(sidNameUse))
if not ret_val: if not ret_val:
raise Exception("Cannot get user SID") raise Exception("Cannot get user SID")
@ -150,7 +151,7 @@ class WindowsUtils(base.BaseOSUtils):
lmi.lgrmi3_domainandname = unicode(username) lmi.lgrmi3_domainandname = unicode(username)
ret_val = netapi32.NetLocalGroupAddMembers(0, unicode(groupname), 3, ret_val = netapi32.NetLocalGroupAddMembers(0, unicode(groupname), 3,
ctypes.addressof(lmi), 1) ctypes.addressof(lmi), 1)
if ret_val == self.NERR_GroupNotFound: if ret_val == self.NERR_GroupNotFound:
raise Exception('Group not found') raise Exception('Group not found')
@ -172,10 +173,12 @@ class WindowsUtils(base.BaseOSUtils):
return None return None
return r.SID 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() token = wintypes.HANDLE()
ret_val = advapi32.LogonUserW(unicode(username), unicode(domain), 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: if not ret_val:
raise Exception("User logon failed") raise Exception("User logon failed")
@ -196,10 +199,10 @@ class WindowsUtils(base.BaseOSUtils):
def get_user_home(self, username): def get_user_home(self, username):
user_sid = self.get_user_sid(username) user_sid = self.get_user_sid(username)
if user_sid: if user_sid:
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\'
'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%s' 'Microsoft\\Windows NT\\CurrentVersion\\'
% user_sid) as key: 'ProfileList\\%s' % user_sid) as key:
return _winreg.QueryValueEx(key, 'ProfileImagePath')[0] return _winreg.QueryValueEx(key, 'ProfileImagePath')[0]
LOG.debug('Home directory not found for user \'%s\'' % username) LOG.debug('Home directory not found for user \'%s\'' % username)
return None return None
@ -220,18 +223,18 @@ class WindowsUtils(base.BaseOSUtils):
conn = wmi.WMI(moniker='//./root/cimv2') conn = wmi.WMI(moniker='//./root/cimv2')
# Get Ethernet adapters only # Get Ethernet adapters only
q = conn.query('SELECT * FROM Win32_NetworkAdapter WHERE ' q = conn.query('SELECT * FROM Win32_NetworkAdapter WHERE '
'AdapterTypeId = 0 AND PhysicalAdapter = True') 'AdapterTypeId = 0 AND PhysicalAdapter = True')
for r in q: for r in q:
l.append(r.Name) l.append(r.Name)
return l return l
def set_static_network_config(self, adapter_name, address, netmask, def set_static_network_config(self, adapter_name, address, netmask,
broadcast, gateway, dnsnameservers): broadcast, gateway, dnsnameservers):
conn = wmi.WMI(moniker='//./root/cimv2') conn = wmi.WMI(moniker='//./root/cimv2')
adapter_name_san = self._sanitize_wmi_input(adapter_name) adapter_name_san = self._sanitize_wmi_input(adapter_name)
q = conn.query('SELECT * FROM Win32_NetworkAdapter ' 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): if not len(q):
raise Exception("Network adapter not found") raise Exception("Network adapter not found")
@ -260,7 +263,7 @@ class WindowsUtils(base.BaseOSUtils):
def set_config_value(self, name, value): def set_config_value(self, name, value):
with _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE, with _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE,
self._config_key) as key: self._config_key) as key:
if type(value) == int: if type(value) == int:
regtype = _winreg.REG_DWORD regtype = _winreg.REG_DWORD
else: else:
@ -270,7 +273,7 @@ class WindowsUtils(base.BaseOSUtils):
def get_config_value(self, name): def get_config_value(self, name):
try: try:
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
self._config_key) as key: self._config_key) as key:
(value, regtype) = _winreg.QueryValueEx(key, name) (value, regtype) = _winreg.QueryValueEx(key, name)
return value return value
except WindowsError: except WindowsError:

View File

@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
class BasePlugin(object): class BasePlugin(object):
def execute(self, service): def execute(self, service):
pass pass

View File

@ -18,17 +18,19 @@ from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.utils import classloader from cloudbaseinit.utils import classloader
opts = [ opts = [
cfg.ListOpt('plugins', default=[ cfg.ListOpt(
'plugins',
default=[
'cloudbaseinit.plugins.windows.sethostname.SetHostNamePlugin', 'cloudbaseinit.plugins.windows.sethostname.SetHostNamePlugin',
'cloudbaseinit.plugins.windows.createuser.CreateUserPlugin', 'cloudbaseinit.plugins.windows.createuser.CreateUserPlugin',
'cloudbaseinit.plugins.windows.networkconfig.NetworkConfigPlugin', 'cloudbaseinit.plugins.windows.networkconfig.NetworkConfigPlugin',
'cloudbaseinit.plugins.windows.sshpublickeys.' 'cloudbaseinit.plugins.windows.sshpublickeys.'
'SetUserSSHPublicKeysPlugin', 'SetUserSSHPublicKeysPlugin',
'cloudbaseinit.plugins.windows.userdata.UserDataPlugin' 'cloudbaseinit.plugins.windows.userdata.UserDataPlugin'
], ],
help='List of enabled plugin classes, ' help='List of enabled plugin classes, '
'to executed in the provided order'), 'to executed in the provided order'),
] ]
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)

View File

@ -25,15 +25,15 @@ from cloudbaseinit.plugins import base
from cloudbaseinit.utils import crypt from cloudbaseinit.utils import crypt
opts = [ opts = [
cfg.StrOpt('username', default='Admin', cfg.StrOpt('username', default='Admin', help='User to be added to the '
help='User to be added to the system or updated if already existing'), 'system or updated if already existing'),
cfg.ListOpt('groups', default=['Administrators'], cfg.ListOpt('groups', default=['Administrators'], help='List of local '
help='List of local groups to which the user specified ' 'groups to which the user specified in \'username\' will '
'in \'username\' will be added'), 'be added'),
cfg.BoolOpt('inject_user_password', default=True, cfg.BoolOpt('inject_user_password', default=True, help='Set the password '
help='Set the password provided in the configuration. ' 'provided in the configuration. If False or no password is '
'If False or no password is provided, a random one will be set'), 'provided, a random one will be set'),
] ]
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)

View File

@ -18,22 +18,22 @@ import re
from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.osutils.factory import * from cloudbaseinit.osutils import factory as osutils_factory
from cloudbaseinit.plugins.base import * from cloudbaseinit.plugins import base
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
opts = [ opts = [
cfg.StrOpt('network_adapter', default=None, cfg.StrOpt('network_adapter', default=None, help='Network adapter to '
help='Network adapter to configure. If not specified, the first ' 'configure. If not specified, the first available ethernet '
'available ethernet adapter will be chosen'), 'adapter will be chosen'),
] ]
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opts(opts) CONF.register_opts(opts)
class NetworkConfigPlugin(): class NetworkConfigPlugin(base.BasePlugin):
def execute(self, service): def execute(self, service):
meta_data = service.get_meta_data('openstack') meta_data = service.get_meta_data('openstack')
if 'network_config' not in meta_data: if 'network_config' not in meta_data:
@ -50,11 +50,12 @@ class NetworkConfigPlugin():
# TODO (alexpilotti): implement a proper grammar # TODO (alexpilotti): implement a proper grammar
m = re.search(r'iface eth0 inet static\s+' m = re.search(r'iface eth0 inet static\s+'
'address\s+(?P<address>[^\s]+)\s+' r'address\s+(?P<address>[^\s]+)\s+'
'netmask\s+(?P<netmask>[^\s]+)\s+' r'netmask\s+(?P<netmask>[^\s]+)\s+'
'broadcast\s+(?P<broadcast>[^\s]+)\s+' r'broadcast\s+(?P<broadcast>[^\s]+)\s+'
'gateway\s+(?P<gateway>[^\s]+)\s+' r'gateway\s+(?P<gateway>[^\s]+)\s+'
'dns\-nameservers\s+(?P<dnsnameservers>[^\r\n]+)\s+', debian_network_conf) r'dns\-nameservers\s+(?P<dnsnameservers>[^\r\n]+)\s+',
debian_network_conf)
if not m: if not m:
raise Exception("network_config format not recognized") raise Exception("network_config format not recognized")
@ -64,7 +65,7 @@ class NetworkConfigPlugin():
gateway = m.group('gateway') gateway = m.group('gateway')
dnsnameservers = m.group('dnsnameservers').strip().split(' ') dnsnameservers = m.group('dnsnameservers').strip().split(' ')
osutils = OSUtilsFactory().get_os_utils() osutils = osutils_factory.OSUtilsFactory().get_os_utils()
network_adapter_name = CONF.network_adapter network_adapter_name = CONF.network_adapter
if not network_adapter_name: if not network_adapter_name:

View File

@ -14,22 +14,21 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from cloudbaseinit.osutils.factory import * from cloudbaseinit.osutils import factory as osutils_factory
from cloudbaseinit.plugins.base import * from cloudbaseinit.plugins import base
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class SetHostNamePlugin(BasePlugin): class SetHostNamePlugin(base.BasePlugin):
def execute(self, service): def execute(self, service):
meta_data = service.get_meta_data('openstack') meta_data = service.get_meta_data('openstack')
if 'hostname' not in meta_data: if 'hostname' not in meta_data:
LOG.debug('Hostname not found in metadata') LOG.debug('Hostname not found in metadata')
return False return False
osutils = OSUtilsFactory().get_os_utils() osutils = osutils_factory.OSUtilsFactory().get_os_utils()
new_host_name = meta_data['hostname'].split('.', 1)[0] new_host_name = meta_data['hostname'].split('.', 1)[0]
return osutils.set_host_name(new_host_name) return osutils.set_host_name(new_host_name)

View File

@ -18,14 +18,14 @@ import os
from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.osutils.factory import * from cloudbaseinit.osutils import factory as osutils_factory
from cloudbaseinit.plugins.base import * from cloudbaseinit.plugins import base
CONF = cfg.CONF CONF = cfg.CONF
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class SetUserSSHPublicKeysPlugin(BasePlugin): class SetUserSSHPublicKeysPlugin(base.BasePlugin):
def execute(self, service): def execute(self, service):
meta_data = service.get_meta_data('openstack') meta_data = service.get_meta_data('openstack')
if not 'public_keys' in meta_data: if not 'public_keys' in meta_data:
@ -33,7 +33,7 @@ class SetUserSSHPublicKeysPlugin(BasePlugin):
username = CONF.username username = CONF.username
osutils = OSUtilsFactory().get_os_utils() osutils = osutils_factory.OSUtilsFactory().get_os_utils()
user_home = osutils.get_user_home(username) user_home = osutils.get_user_home(username)
if not user_home: if not user_home:

View File

@ -14,18 +14,19 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import os
import re import re
import tempfile import tempfile
import uuid import uuid
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.osutils.factory import * from cloudbaseinit.osutils import factory as osutils_factory
from cloudbaseinit.plugins.base import * from cloudbaseinit.plugins import base
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class UserDataPlugin(): class UserDataPlugin(base.BasePlugin):
def execute(self, service): def execute(self, service):
user_data = service.get_user_data('openstack') user_data = service.get_user_data('openstack')
if not user_data: if not user_data:
@ -33,7 +34,7 @@ class UserDataPlugin():
LOG.debug('User data content:\n%s' % user_data) 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())) target_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))
if re.search(r'^rem cmd\s', user_data, re.I): 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 stdout:\n%s' % out)
LOG.debug('User_data stderr:\n%s' % err) LOG.debug('User_data stderr:\n%s' % err)
except Exception, ex: 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: finally:
if os.path.exists(target_path): if os.path.exists(target_path):
os.remove(target_path) os.remove(target_path)
return False return False

View File

@ -16,9 +16,9 @@
import sys import sys
from cloudbaseinit import init
from cloudbaseinit.openstack.common import cfg from cloudbaseinit.openstack.common import cfg
from cloudbaseinit.openstack.common import log as logging2 from cloudbaseinit.openstack.common import log as logging2
from cloudbaseinit.init import *
CONF = cfg.CONF CONF = cfg.CONF
LOG = logging2.getLogger(__name__) LOG = logging2.getLogger(__name__)
@ -28,7 +28,4 @@ def main():
CONF(sys.argv[1:]) CONF(sys.argv[1:])
logging2.setup('cloudbaseinit') logging2.setup('cloudbaseinit')
init = InitManager() init.InitManager().configure_host()
init.configure_host()

View File

@ -28,6 +28,7 @@ else:
openssl = ctypes.CDLL(openssl_lib_path) openssl = ctypes.CDLL(openssl_lib_path)
clib = ctypes.CDLL(ctypes.util.find_library("c")) clib = ctypes.CDLL(ctypes.util.find_library("c"))
class RSA(ctypes.Structure): class RSA(ctypes.Structure):
_fields_ = [ _fields_ = [
("pad", ctypes.c_int), ("pad", ctypes.c_int),

View File

@ -22,26 +22,26 @@ requires = common_setup.parse_requirements()
dependency_links = common_setup.parse_dependency_links() dependency_links = common_setup.parse_dependency_links()
setuptools.setup(name='cloudbase-init', setuptools.setup(name='cloudbase-init',
version='0.9.0', version='0.9.0',
description='Portable cloud initialization service', description='Portable cloud initialization service',
author='Cloudbase Solutions Srl', author='Cloudbase Solutions Srl',
author_email='apilotti@cloudbasesolutions.com', author_email='apilotti@cloudbasesolutions.com',
url='http://www.cloudbase.it/', url='http://www.cloudbase.it/',
classifiers=[ classifiers=['Environment :: OpenStack',
'Environment :: OpenStack', 'Intended Audience :: Information Technology',
'Intended Audience :: Information Technology', 'Intended Audience :: System Administrators',
'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software '
'License :: OSI Approved :: Apache Software License', 'License',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7'],
], cmdclass=common_setup.get_cmdclass(),
cmdclass=common_setup.get_cmdclass(), packages=setuptools.find_packages(exclude=['bin']),
packages=setuptools.find_packages(exclude=['bin']), install_requires=requires,
install_requires=requires, dependency_links=dependency_links,
dependency_links=dependency_links, include_package_data=True,
include_package_data=True, setup_requires=['setuptools_git>=0.4'],
setup_requires=['setuptools_git>=0.4'], entry_points={'console_scripts':
entry_points={'console_scripts': ['cloudbase-init = cloudbaseinit.shell:main']}, ['cloudbase-init = cloudbaseinit.shell:main']},
py_modules=[]) py_modules=[])