"""
import ConfigParser
+import errno
+import grp
import json
import logging
import os
+import os.path
+import pwd
import rpmUtils.updates as rpmupdates
import rpmUtils.miscutils as rpmutils
import subprocess
* apt
* yum
"""
+ if not self._packages:
+ return
packages = sorted(self._packages.iteritems(), PackagesHandler._pkgsort)
for manager, package_entries in packages:
else:
handler(self, package_entries)
+class FilesHandler(object):
+ def __init__(self, files):
+ self._files = files
+
+ def apply_files(self):
+ if not self._files:
+ return
+ for fdest, meta in self._files.iteritems():
+ dest = fdest.encode()
+ try:
+ os.makedirs(os.path.dirname(dest))
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ logging.debug(str(e))
+ else:
+ logging.exception(e)
+
+ if 'content' in meta:
+ if isinstance(meta['content'], basestring):
+ f = open(dest, 'w')
+ f.write(meta['content'])
+ f.close()
+ else:
+ f = open(dest, 'w')
+ f.write(json.dumps(meta['content'], indent=4))
+ f.close()
+ elif 'source' in meta:
+ CommandRunner('wget -O %s %s' % (dest, meta['source'])).run()
+ else:
+ logging.error('%s %s' % (dest, str(meta)))
+ continue
+
+ uid = -1
+ gid = -1
+ if 'owner' in meta:
+ try:
+ user_info = pwd.getpwnam(meta['owner'])
+ uid = user_info[2]
+ except KeyError as ex:
+ pass
+
+ if 'group' in meta:
+ try:
+ group_info = grp.getgrnam(meta['group'])
+ gid = group_info[2]
+ except KeyError as ex:
+ pass
+
+ os.chown(dest, uid, gid)
+ if 'mode' in meta:
+ os.chmod(dest, int(meta['mode'], 8))
+
class ServicesHandler(object):
_services = {}
"""
Starts, stops, enables, disables services
"""
+ if not self._services:
+ return
for manager, service_entries in self._services.iteritems():
handler = self._service_handler(manager)
if not handler:
"""
Restarts failed services, and runs hooks.
"""
+ if not self._services:
+ return
for manager, service_entries in self._services.iteritems():
handler = self._service_handler(manager)
if not handler:
self._is_local_metadata = True
self._metadata = None
- def retrieve(self):
+ def retrieve(self, meta_str=None):
"""
- Read the metadata from the given filename and return the string
+ Read the metadata from the given filename
"""
- f = open("/var/lib/cloud/data/cfn-init-data")
- self._data = f.read()
- f.close()
+ if meta_str:
+ self._data = meta_str
+ else:
+ f = open("/var/lib/cloud/data/cfn-init-data")
+ self._data = f.read()
+ f.close()
+
if isinstance(self._data, str):
self._metadata = json.loads(self._data)
else:
* sources (not yet)
* users (not yet)
* groups (not yet)
- * files (not yet)
+ * files
* commands (not yet)
* services
"""
#FIXME: handle sources
#FIXME: handle users
#FIXME: handle groups
- #FIXME: handle files
+ FilesHandler(self._config.get("files")).apply_files()
#FIXME: handle commands
ServicesHandler(self._config.get("services")).apply_services()
import nose
from nose.plugins.attrib import attr
from nose import with_setup
+import shutil
from heat.cfntools.cfn_helper import *
assert(c.hooks['bla'].runas == 'root')
+def tearDown_metadata_files():
+ shutil.rmtree('/tmp/_files_test_', ignore_errors=True)
+
+
+@with_setup(None, tearDown_metadata_files)
+@attr(tag=['unit', 'cfn-metadata'])
+@attr(speed='fast')
+def test_metadata_files():
+
+ j = ''' {
+ "AWS::CloudFormation::Init" : {
+ "config" : {
+ "files" : {
+ "/tmp/_files_test_/epel.repo" : {
+ "source" : "https://raw.github.com/heat-api/heat/master/README.rst",
+ "mode" : "000644"
+ },
+ "/tmp/_files_test_/_with/some/dirs/to/make/small.conf" : {
+ "content" : "not much really",
+ "mode" : "000777"
+ },
+ "/tmp/_files_test_/node.json": {
+ "content": {
+ "myapp": {
+ "db": {
+ "database": "RefDBName",
+ "user": "RefDBUser",
+ "host": "Fn::GetAttDBInstance.Endpoint.Address",
+ "password": "RefDBPassword"
+ }
+ },
+ "run_list": ["recipe[wordpress]", "bla"]
+ },
+ "mode": "000600"
+ }
+ }
+ }
+ }
+ }
+'''
+
+ metadata = Metadata('tester',
+ 'ronald')
+ metadata.retrieve(j)
+ metadata.cfn_init()
+
+ # mask out the file type
+ mask = int('007777', 8)
+ assert(os.stat('/tmp/_files_test_/node.json').st_mode & mask == 0600)
+ assert(os.stat('/tmp/_files_test_/epel.repo').st_mode & mask == 0644)
+ assert(os.stat('/tmp/_files_test_/_with/some/dirs/to/make/small.conf').st_mode & mask == 0777)
+
if __name__ == '__main__':
sys.argv.append(__file__)
nose.main()