Add instance cloudinit support

implements blueprint guestagent-through-userdata

Change-Id: Ifb33f149e63d7b9b7ed676da8ff05085ceceffeb
This commit is contained in:
Andrey Shestakov 2013-08-15 18:09:29 +03:00
parent aa5c3ddf1b
commit d523f31c57
5 changed files with 79 additions and 2 deletions

View File

@ -0,0 +1,3 @@
These cloudinit scripts will used as userdata on instance create
File names should match pattern: service_type.cloudinit
For example: mysql.cloudinit

View File

@ -174,6 +174,8 @@ common_opts = [
cfg.StrOpt('nova_proxy_admin_tenant_name', default='', cfg.StrOpt('nova_proxy_admin_tenant_name', default='',
help="Admin tenant used to connect to Nova"), help="Admin tenant used to connect to Nova"),
cfg.StrOpt('network_label_regex', default='^private$'), cfg.StrOpt('network_label_regex', default='^private$'),
cfg.StrOpt('cloudinit_location', default='/etc/trove/cloudinit',
help="Path to folder with cloudinit scripts"),
] ]

View File

@ -13,7 +13,7 @@
# under the License. # under the License.
import traceback import traceback
import os.path
from cinderclient import exceptions as cinder_exceptions from cinderclient import exceptions as cinder_exceptions
from eventlet import greenthread from eventlet import greenthread
from novaclient import exceptions as nova_exceptions from novaclient import exceptions as nova_exceptions
@ -334,10 +334,17 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
files = {"/etc/guest_info": ("[DEFAULT]\nguest_id=%s\n" files = {"/etc/guest_info": ("[DEFAULT]\nguest_id=%s\n"
"service_type=%s\n" % "service_type=%s\n" %
(self.id, service_type))} (self.id, service_type))}
userdata = None
cloudinit = os.path.join(CONF.get('cloudinit_location'),
"%s.cloudinit" % service_type)
if os.path.isfile(cloudinit):
with open(cloudinit, "r") as f:
userdata = f.read()
name = self.hostname or self.name name = self.hostname or self.name
bdmap = block_device_mapping bdmap = block_device_mapping
server = self.nova_client.servers.create(name, image_id, flavor_id, server = self.nova_client.servers.create(name, image_id, flavor_id,
files=files, files=files,
userdata=userdata,
security_groups= security_groups=
security_groups, security_groups,
block_device_mapping=bdmap) block_device_mapping=bdmap)

View File

@ -262,7 +262,7 @@ class FakeServers(object):
return (self.context.is_admin or return (self.context.is_admin or
server.owner.tenant == self.context.tenant) server.owner.tenant == self.context.tenant)
def create(self, name, image_id, flavor_ref, files=None, def create(self, name, image_id, flavor_ref, files=None, userdata=None,
block_device_mapping=None, volume=None, security_groups=None): block_device_mapping=None, volume=None, security_groups=None):
id = "FAKE_%s" % uuid.uuid4() id = "FAKE_%s" % uuid.uuid4()
if volume: if volume:

View File

@ -19,6 +19,71 @@ import trove.backup.models as backup_models
from trove.common.exception import TroveError from trove.common.exception import TroveError
from mockito import mock, when, unstub, any, verify, never from mockito import mock, when, unstub, any, verify, never
from swiftclient.client import ClientException from swiftclient.client import ClientException
from tempfile import NamedTemporaryFile
import os
class fake_Server:
def __init__(self):
self.id = None
self.name = None
self.image_id = None
self.flavor_id = None
self.files = None
self.userdata = None
self.security_groups = None
self.block_device_mapping = None
class fake_ServerManager:
def create(self, name, image_id, flavor_id, files, userdata,
security_groups, block_device_mapping):
server = fake_Server()
server.id = "server_id"
server.name = name
server.image_id = image_id
server.flavor_id = flavor_id
server.files = files
server.userdata = userdata
server.security_groups = security_groups
server.block_device_mapping = block_device_mapping
return server
class fake_nova_client:
def __init__(self):
self.servers = fake_ServerManager()
class FreshInstanceTasksTest(testtools.TestCase):
def setUp(self):
super(FreshInstanceTasksTest, self).setUp()
when(taskmanager_models.FreshInstanceTasks).id().thenReturn(
"instance_id")
when(taskmanager_models.FreshInstanceTasks).hostname().thenReturn(
"hostname")
taskmanager_models.FreshInstanceTasks.nova_client = fake_nova_client()
taskmanager_models.CONF = mock()
self.userdata = "hello moto"
with NamedTemporaryFile(suffix=".cloudinit", delete=False) as f:
self.cloudinit = f.name
f.write(self.userdata)
self.freshinstancetasks = taskmanager_models.FreshInstanceTasks(
None, None, None, None)
def tearDown(self):
super(FreshInstanceTasksTest, self).tearDown()
os.remove(self.cloudinit)
unstub()
def test_create_instance_userdata(self):
cloudinit_location = os.path.dirname(self.cloudinit)
service_type = os.path.splitext(os.path.basename(self.cloudinit))[0]
when(taskmanager_models.CONF).get("cloudinit_location").thenReturn(
cloudinit_location)
server = self.freshinstancetasks._create_server(None, None, None,
service_type, None)
self.assertEqual(server.userdata, self.userdata)
class BackupTasksTest(testtools.TestCase): class BackupTasksTest(testtools.TestCase):