-
Notifications
You must be signed in to change notification settings - Fork 52
/
create.py
162 lines (138 loc) · 6.53 KB
/
create.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python
import os
from datetime import datetime
from os.path import join, dirname
from cloudify import ctx
ctx.download_resource(
join('components', 'utils.py'),
join(dirname(__file__), 'utils.py'))
import utils # NOQA
NODE_NAME = 'manager-resources'
ctx_properties = utils.ctx_factory.create(NODE_NAME)
def execute_before_bootstrap():
exec_paths = ctx_properties['execute_before_bootstrap']
for path in exec_paths:
delete_tmp_path = False
# TODO: Upon moving to Python 3, convert to urllib2.urlparse
if '://' in path and path.split('://', 1)[0] in ('http', 'https'):
path = utils.download_file(path)
utils.chmod('744', path)
delete_tmp_path = True
utils.run(path)
if delete_tmp_path:
utils.remove(path)
def deploy_manager_sources():
"""Deploys all manager sources from a single archive.
"""
archive_path = ctx_properties['manager_resources_package']
archive_checksum_path = \
ctx_properties['manager_resources_package_checksum_file']
skip_checksum_validation = ctx_properties['skip_checksum_validation']
utils.mkdir(utils.AGENT_ARCHIVES_PATH)
if archive_path:
sources_agents_path = os.path.join(
utils.CLOUDIFY_SOURCES_PATH, 'agents')
# this will leave this several hundreds of MBs archive on the
# manager. should find a way to clean it after all operations
# were completed and bootstrap succeeded as it is not longer
# necessary
utils.mkdir(utils.CLOUDIFY_SOURCES_PATH)
resource_name = os.path.basename(archive_path)
destination = os.path.join(utils.CLOUDIFY_SOURCES_PATH, resource_name)
ctx.logger.info('Downloading manager resources package...')
resources_archive_path = \
utils.download_cloudify_resource(
archive_path, NODE_NAME, destination=destination)
# This would ideally go under utils.download_cloudify_resource but as
# of now, we'll only be validating the manager resources package.
if not skip_checksum_validation:
ctx.logger.info('Validating checksum...')
skip_if_failed = False
if not archive_checksum_path:
skip_if_failed = True
archive_checksum_path = archive_path + '.md5'
md5_name = os.path.basename(archive_checksum_path)
destination = os.path.join(utils.CLOUDIFY_SOURCES_PATH, md5_name)
resources_archive_md5_path = utils.download_cloudify_resource(
archive_checksum_path, NODE_NAME, destination=destination)
if not utils.validate_md5_checksum(resources_archive_path,
resources_archive_md5_path):
if skip_if_failed:
ctx.logger.warn('Checksum validation failed. '
'Continuing as no checksum file was '
'explicitly provided.')
else:
ctx.abort_operation(
'Failed to validate checksum for {0}'.format(
resources_archive_path))
else:
ctx.logger.info('Resources Package downloaded successfully...')
else:
ctx.logger.info(
'Skipping resources package checksum validation...')
utils.untar(
resources_archive_path,
utils.CLOUDIFY_SOURCES_PATH,
skip_old_files=True)
def splitext(filename):
# not using os.path.splitext as it would return .gz instead of
# .tar.gz
if filename.endswith('.tar.gz'):
return '.tar.gz'
elif filename.endswith('.exe'):
return '.exe'
else:
ctx.abort_operation(
'Unknown agent format for {0}. '
'Must be either tar.gz or exe'.format(filename))
def normalize_agent_name(filename):
# this returns the normalized name of an agent upon which our agent
# installer retrieves agent packages for installation.
# e.g. Ubuntu-trusty-agent_3.4.0-m3-b392.tar.gz returns
# ubuntu-trusty-agent
return filename.split('_', 1)[0].lower()
def backup_agent_resources(agents_dir):
ctx.logger.info('Backing up agents in {0}...'.format(agents_dir))
if not os.path.isdir(utils.AGENTS_ROLLBACK_PATH):
utils.mkdir(utils.AGENTS_ROLLBACK_PATH)
utils.copy(agents_dir, utils.AGENTS_ROLLBACK_PATH)
def restore_agent_resources(agents_dir):
ctx.logger.info('Restoring agents in {0}'.format(
utils.AGENTS_ROLLBACK_PATH))
if os.path.isdir(agents_dir):
utils.remove(agents_dir)
utils.mkdir(agents_dir)
utils.copy(os.path.join(utils.AGENTS_ROLLBACK_PATH, 'agents', '.'),
agents_dir)
manager_scripts_path = os.path.join(
utils.MANAGER_RESOURCES_HOME, 'packages', 'scripts')
manager_templates_path = os.path.join(
utils.MANAGER_RESOURCES_HOME, 'packages', 'templates')
if utils.is_upgrade:
backup_agent_resources(utils.AGENT_ARCHIVES_PATH)
utils.remove(utils.AGENT_ARCHIVES_PATH)
utils.mkdir(utils.AGENT_ARCHIVES_PATH)
utils.remove(manager_scripts_path)
utils.remove(manager_templates_path)
ctx.logger.info('Upgrading agents...')
elif utils.is_rollback:
ctx.logger.info('Restoring agents...')
restore_agent_resources(utils.AGENT_ARCHIVES_PATH)
for agent_file in os.listdir(sources_agents_path):
agent_id = normalize_agent_name(agent_file)
agent_extension = splitext(agent_file)
utils.move(
os.path.join(sources_agents_path, agent_file),
os.path.join(utils.AGENT_ARCHIVES_PATH,
agent_id + agent_extension)
)
def store_manager_version():
version = os.environ.get('MANAGER_VERSION', '')
build_date = datetime.now().strftime('%Y-%m-%d %H:%M')
motd = ' '.join(['Cloudify Manager', version,
'(bootstrap {0})'.format(build_date)])
# easiest way to sudo-append to file without changing its chmod...
utils.sudo(['bash', '-c', "echo '{0}' >> /etc/motd".format(motd)])
execute_before_bootstrap()
deploy_manager_sources()
store_manager_version()