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='',
help="Admin tenant used to connect to Nova"),
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.
import traceback
import os.path
from cinderclient import exceptions as cinder_exceptions
from eventlet import greenthread
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"
"service_type=%s\n" %
(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
bdmap = block_device_mapping
server = self.nova_client.servers.create(name, image_id, flavor_id,
files=files,
userdata=userdata,
security_groups=
security_groups,
block_device_mapping=bdmap)

View File

@ -262,7 +262,7 @@ class FakeServers(object):
return (self.context.is_admin or
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):
id = "FAKE_%s" % uuid.uuid4()
if volume:

View File

@ -19,6 +19,71 @@ import trove.backup.models as backup_models
from trove.common.exception import TroveError
from mockito import mock, when, unstub, any, verify, never
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):