""" Installs and configures an openstack swift """ import logging import os import uuid import engine_validators as validate import basedefs import common_utils as utils from ospluginutils import NovaConfig, getManifestTemplate, appendManifestFile # Controller object will be initialized from main flow controller = None # Plugin name PLUGIN_NAME = "OS-SWIFT" PLUGIN_NAME_COLORED = utils.getColoredText(PLUGIN_NAME, basedefs.BLUE) logging.debug("plugin %s loaded", __name__) def initConfig(controllerObject): global controller controller = controllerObject logging.debug("Adding Openstack swift configuration") paramsList = [ {"CMD_OPTION" : "os-swift-proxy", "USAGE" : "A comma seperated list of IP addresses on which to install the Swift proxy services", "PROMPT" : "A comma seperated list of IP addresses on which to install the Swift proxy services", "OPTION_LIST" : [], "VALIDATION_FUNC" : validate.validatePing, "DEFAULT_VALUE" : "127.0.0.1", "MASK_INPUT" : False, "LOOSE_VALIDATION": True, "CONF_NAME" : "CONFIG_SWIFT_PROXY_HOSTS", "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, {"CMD_OPTION" : "os-swift-storage", "USAGE" : "A comma seperated list of IP addresses on which to install the Swift Storage services, each entry should take the format [/dev], for example 127.0.0.1/vdb will install /dev/vdb on 127.0.0.1 as a swift storage device, if /dev is ommited packstack will create a loopback device for a test setup", "PROMPT" : "Hostname of the Swift Storage servers e.g. host/dev,host/dev", "OPTION_LIST" : [], "VALIDATION_FUNC" : validate.validateStringNotEmpty, "DEFAULT_VALUE" : "127.0.0.1", "MASK_INPUT" : False, "LOOSE_VALIDATION": True, "CONF_NAME" : "CONFIG_SWIFT_STORAGE_HOSTS", "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, {"CMD_OPTION" : "os-swift-storage-zones", "USAGE" : "Number of swift storage zones, this number MUST be no bigger then number of storage devices configered", "PROMPT" : "Number of swift storage zones, this number MUST be no bigger then number of storage devices configered", "OPTION_LIST" : [], "VALIDATION_FUNC" : validate.validateInteger, "DEFAULT_VALUE" : "1", "MASK_INPUT" : False, "LOOSE_VALIDATION": True, "CONF_NAME" : "CONFIG_SWIFT_STORAGE_ZONES", "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, {"CMD_OPTION" : "os-swift-storage-replicas", "USAGE" : "Number of swift storage replicas, this number MUST be no bigger then number of storage zones configered", "PROMPT" : "Number of swift storage replicas, this number MUST be no bigger then number of storage zones configered", "OPTION_LIST" : [], "VALIDATION_FUNC" : validate.validateInteger, "DEFAULT_VALUE" : "1", "MASK_INPUT" : False, "LOOSE_VALIDATION": True, "CONF_NAME" : "CONFIG_SWIFT_STORAGE_REPLICAS", "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, {"CMD_OPTION" : "os-swift-storage-fstype", "USAGE" : "FileSystem type for storage nodes", "PROMPT" : "FileSystem type for storage nodes", "OPTION_LIST" : ['xfs','ext4'], "VALIDATION_FUNC" : validate.validateOptions, "DEFAULT_VALUE" : "ext4", "MASK_INPUT" : False, "LOOSE_VALIDATION": True, "CONF_NAME" : "CONFIG_SWIFT_STORAGE_FSTYPE", "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, ] groupDict = { "GROUP_NAME" : "OSSWIFT", "DESCRIPTION" : "OpenStack Swift Config paramaters", "PRE_CONDITION" : "CONFIG_SWIFT_INSTALL", "PRE_CONDITION_MATCH" : "y", "POST_CONDITION" : False, "POST_CONDITION_MATCH" : True} controller.addGroup(groupDict, paramsList) def initSequences(controller): if controller.CONF['CONFIG_SWIFT_INSTALL'] != 'y': return steps = [ {'title': 'Adding Swift Keystone Manifest entries', 'functions':[createkeystonemanifest]}, {'title': 'Creating OS Swift builder Manifests', 'functions':[createbuildermanifest]}, {'title': 'Creating OS Swift proxy Manifests', 'functions':[createproxymanifest]}, {'title': 'Creating OS Swift storage Manifests', 'functions':[createstoragemanifest]}, {'title': 'Creating OS Swift Common Manifests', 'functions':[createcommonmanifest]}, ] controller.addSequence("Installing OpenStack Swift", [], [], steps) def createkeystonemanifest(): manifestfile = "%s_keystone.pp"%controller.CONF['CONFIG_KEYSTONE_HOST'] controller.CONF['CONFIG_SWIFT_PROXY'] = controller.CONF['CONFIG_SWIFT_PROXY_HOSTS'].split(',')[0] manifestdata = getManifestTemplate("keystone_swift.pp") appendManifestFile(manifestfile, manifestdata) devices = [] def parseDevices(config_swift_storage_hosts): device_number = 0 for host in config_swift_storage_hosts.split(","): device_number += 1 device = None if '/' in host: host, device = host.split('/')[0:2] zone = (device_number % int(controller.CONF["CONFIG_SWIFT_STORAGE_ZONES"]))+1 devices.append({'host':host, 'device':device, 'device_name':'device%s'%device_number, 'zone':str(zone)}) return devices # The ring file should be built and distributed befor the storage services # come up. Specifically the replicator crashes if the ring isn't present def createbuildermanifest(): # TODO : put this on the proxy server, will need to change this later controller.CONF['CONFIG_SWIFT_BUILDER_HOST'] = controller.CONF['CONFIG_SWIFT_PROXY_HOSTS'].split(',')[0] manifestfile = "%s_ring_swift.pp"%controller.CONF['CONFIG_SWIFT_BUILDER_HOST'] manifestdata = getManifestTemplate("swift_builder.pp") # Add each device to the ring devicename = 0 for device in parseDevices(controller.CONF["CONFIG_SWIFT_STORAGE_HOSTS"]): host = device['host'] devicename = device['device_name'] zone = device['zone'] manifestdata = manifestdata + '\n@@ring_object_device { "%s:6000/%s":\n zone => %s,\n weight => 10, }'%(host, devicename, zone) manifestdata = manifestdata + '\n@@ring_container_device { "%s:6001/%s":\n zone => %s,\n weight => 10, }'%(host, devicename, zone) manifestdata = manifestdata + '\n@@ring_account_device { "%s:6002/%s":\n zone => %s,\n weight => 10, }'%(host, devicename, zone) appendManifestFile(manifestfile, manifestdata) def createproxymanifest(): manifestfile = "%s_swift.pp"%controller.CONF['CONFIG_SWIFT_PROXY_HOSTS'] manifestdata = getManifestTemplate("swift_proxy.pp") # If the proxy server is also a storage server then swift::ringsync will be included for the storage server if controller.CONF['CONFIG_SWIFT_PROXY_HOSTS'] not in controller.CONF["CONFIG_SWIFT_STORAGE_HOSTS"].split(","): manifestdata += 'swift::ringsync{["account","container","object"]:\n ring_server => "%s"\n}'%controller.CONF['CONFIG_SWIFT_BUILDER_HOST'] appendManifestFile(manifestfile, manifestdata) def createstoragemanifest(): # this need to happen once per storage host for host in set([device['host'] for device in devices]): controller.CONF["CONFIG_SWIFT_STORAGE_CURRENT"] = host manifestfile = "%s_swift.pp"%host manifestdata = getManifestTemplate("swift_storage.pp") appendManifestFile(manifestfile, manifestdata) # this need to happen once per storage device for device in devices: host = device['host'] devicename = device['device_name'] device = device['device'] server = utils.ScriptRunner(host) validate.r_validateDevice(server, device) server.execute() manifestfile = "%s_swift.pp"%host if device: manifestdata = "\n" + 'swift::storage::%s{"%s":\n device => "/dev/%s",\n}'% (controller.CONF["CONFIG_SWIFT_STORAGE_FSTYPE"], devicename, device) else: controller.CONF["SWIFT_STORAGE_DEVICES"] = "'%s'"%devicename manifestdata = "\n" + getManifestTemplate("swift_loopback.pp") appendManifestFile(manifestfile, manifestdata) def createcommonmanifest(): for manifestfile in controller.CONF['CONFIG_MANIFESTFILES']: if manifestfile.endswith("_swift.pp"): data = getManifestTemplate("swift_common.pp") appendManifestFile(os.path.split(manifestfile)[1], data)