Add initial Archiver
This commit is contained in:
parent
7266c3b98c
commit
63bd68cc2a
@ -19,7 +19,7 @@ workflows:
|
|||||||
- Common.xml
|
- Common.xml
|
||||||
|
|
||||||
heat_templates:
|
heat_templates:
|
||||||
Windows.template
|
- Windows.template
|
||||||
|
|
||||||
agent_templates:
|
agent_templates:
|
||||||
- SetPassword.template
|
- SetPassword.template
|
||||||
|
91
archiver.py
Normal file
91
archiver.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
import os
|
||||||
|
import tarfile
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
import logging as log
|
||||||
|
|
||||||
|
from consts import DATA_TYPES
|
||||||
|
|
||||||
|
|
||||||
|
class Archiver(object):
|
||||||
|
def __init__(self,
|
||||||
|
ui_forms_target="service_forms",
|
||||||
|
workflows_target="workflows",
|
||||||
|
heat_templates_target="templates/cf",
|
||||||
|
agent_templates_target="templates/agent",
|
||||||
|
scripts_target="templates/agent/scripts"):
|
||||||
|
"""
|
||||||
|
ui_forms_target -- relative path for a ui_forms location in
|
||||||
|
resulted archive
|
||||||
|
workflows_target -- relative path for a desired workflow location in
|
||||||
|
resulted archive
|
||||||
|
heat_templates_target -- relative path for a desired heat templates
|
||||||
|
location in resulted archive
|
||||||
|
agent_templates_target -- relative path for a heat templates location
|
||||||
|
scripts_target -- relative path for a agent script location
|
||||||
|
"""
|
||||||
|
self.archive_structure = {"ui_forms": ui_forms_target,
|
||||||
|
"workflows": workflows_target,
|
||||||
|
"heat_templates": heat_templates_target,
|
||||||
|
"agent_templates": agent_templates_target,
|
||||||
|
"scripts": scripts_target
|
||||||
|
}
|
||||||
|
|
||||||
|
def create(self, manifests, *types):
|
||||||
|
"""
|
||||||
|
manifests -- list of Manifest objects
|
||||||
|
*types - desired data types to be added to archive
|
||||||
|
"""
|
||||||
|
temp_dir = tempfile.mkdtemp()
|
||||||
|
for data_type in types:
|
||||||
|
if data_type not in DATA_TYPES:
|
||||||
|
raise Exception("Please, specify one of the supported data "
|
||||||
|
"types: {0}".format(DATA_TYPES))
|
||||||
|
|
||||||
|
for manifest in manifests:
|
||||||
|
if not manifest.enabled and not manifest.valid:
|
||||||
|
continue
|
||||||
|
if hasattr(manifest, data_type):
|
||||||
|
dst_directory = os.path.join(temp_dir,
|
||||||
|
self.archive_structure[
|
||||||
|
data_type])
|
||||||
|
if not os.path.exists(dst_directory):
|
||||||
|
os.makedirs(dst_directory)
|
||||||
|
|
||||||
|
for file_path in getattr(manifest, data_type):
|
||||||
|
basedir, filename = os.path.split(file_path)
|
||||||
|
destination = os.path.join(dst_directory,
|
||||||
|
filename)
|
||||||
|
try:
|
||||||
|
shutil.copyfile(file_path, destination)
|
||||||
|
except IOError:
|
||||||
|
log.error("Unable to copy file "
|
||||||
|
"{0}".format(file))
|
||||||
|
else:
|
||||||
|
log.info(
|
||||||
|
"Manifest for {0} service has no file definitions for "
|
||||||
|
"{1}").format(manifest.service_display_name, data_type)
|
||||||
|
|
||||||
|
with tarfile.open("sample.tar", "w") as tar:
|
||||||
|
tar.add(temp_dir)
|
||||||
|
try:
|
||||||
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||||
|
except Exception as e:
|
||||||
|
log.error("Unable to delete temp directory: {0}".format(e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
13
cmd/__init__.py
Normal file
13
cmd/__init__.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
28
cmd/run.py
Normal file
28
cmd/run.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
from parser import ManifestParser
|
||||||
|
from archiver import Archiver
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = ManifestParser(os.path.join(os.path.dirname(__file__), os.pardir,
|
||||||
|
'Services'))
|
||||||
|
manifests = parser.parse()
|
||||||
|
Archiver().create(manifests, "ui_forms", "heat_templates", "agent_templates")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
19
consts.py
Normal file
19
consts.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
UI_FORMS = "ui_forms"
|
||||||
|
WORKFLOWS = "workflows"
|
||||||
|
HEAT_TEMPLATES = "heat_templates"
|
||||||
|
AGENT_TEMPLATES = "agent_templates"
|
||||||
|
SCRIPTS = "scripts"
|
||||||
|
DATA_TYPES = [UI_FORMS, WORKFLOWS, HEAT_TEMPLATES, AGENT_TEMPLATES, SCRIPTS]
|
17
manifest.py
17
manifest.py
@ -1,6 +1,19 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
class Manifest(object):
|
class Manifest(object):
|
||||||
def __init__(self, initial_data):
|
def __init__(self, initial_data):
|
||||||
for key in initial_data:
|
for key in initial_data:
|
||||||
setattr(self, key, initial_data[key])
|
setattr(self, key, initial_data[key])
|
||||||
self.valid = True
|
|
51
parser.py
51
parser.py
@ -1,7 +1,20 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
import logging as log
|
import logging as log
|
||||||
|
|
||||||
from manifest import Manifest
|
from manifest import Manifest
|
||||||
|
|
||||||
|
|
||||||
@ -17,9 +30,11 @@ class ManifestParser(object):
|
|||||||
"""
|
"""
|
||||||
manifest_directory -- absolute path to the directory with manifests
|
manifest_directory -- absolute path to the directory with manifests
|
||||||
ui_forms_directory -- absolute or relative path to ui forms definitions
|
ui_forms_directory -- absolute or relative path to ui forms definitions
|
||||||
workflows_directory -- absolute or relative path to workflow definitions
|
workflows_directory -- absolute or relative path to workflow
|
||||||
|
definitions
|
||||||
heat_templates_directory -- absolute or relative path to heat templates
|
heat_templates_directory -- absolute or relative path to heat templates
|
||||||
agent_templates_directory --absolute or relative path to agent templates
|
agent_templates_directory --absolute or relative path to agent
|
||||||
|
templates
|
||||||
scripts_directory -- absolute or relative path to scripts
|
scripts_directory -- absolute or relative path to scripts
|
||||||
"""
|
"""
|
||||||
if not os.path.isabs(ui_forms_directory):
|
if not os.path.isabs(ui_forms_directory):
|
||||||
@ -41,7 +56,7 @@ class ManifestParser(object):
|
|||||||
self.manifest_directory = manifest_directory
|
self.manifest_directory = manifest_directory
|
||||||
self.directory_mapping = {"ui_forms": ui_forms_directory,
|
self.directory_mapping = {"ui_forms": ui_forms_directory,
|
||||||
"workflows": workflows_directory,
|
"workflows": workflows_directory,
|
||||||
"heat_templates_directory":
|
"heat_templates":
|
||||||
heat_templates_directory,
|
heat_templates_directory,
|
||||||
"agent_templates": agent_templates_directory,
|
"agent_templates": agent_templates_directory,
|
||||||
"scripts": scripts_directory
|
"scripts": scripts_directory
|
||||||
@ -60,21 +75,29 @@ class ManifestParser(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
with open(manifest_file) as stream:
|
with open(manifest_file) as stream:
|
||||||
service_manifest_descr = yaml.load(stream)
|
service_manifest_data = yaml.load(stream)
|
||||||
except yaml.YAMLError, exc:
|
except yaml.YAMLError, exc:
|
||||||
log.warn("Failed to load manifest file. {0}. "
|
log.warn("Failed to load manifest file. {0}. "
|
||||||
"The reason: {1!s}".format(manifest_file,
|
"The reason: {1!s}".format(manifest_file,
|
||||||
exc))
|
exc))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for key, value in service_manifest_descr.iteritems():
|
valid_file_info = True
|
||||||
valid_file_info = True
|
for key, value in service_manifest_data.iteritems():
|
||||||
directory_location = self.directory_mapping.get(key)
|
directory_location = self.directory_mapping.get(key)
|
||||||
if directory_location:
|
if directory_location:
|
||||||
|
if not isinstance(value, list):
|
||||||
|
log.error("{0} section should represent a file"
|
||||||
|
" listing in manifest {1}"
|
||||||
|
"".format(directory_location, file))
|
||||||
|
valid_file_info = False
|
||||||
|
continue
|
||||||
for i, filename in enumerate(value):
|
for i, filename in enumerate(value):
|
||||||
absolute_path = os.path.join(directory_location,
|
absolute_path = os.path.join(directory_location,
|
||||||
filename)
|
filename)
|
||||||
service_manifest_descr[key][i] = absolute_path
|
|
||||||
|
service_manifest_data[key][i] = absolute_path
|
||||||
|
|
||||||
if not os.path.exists(absolute_path):
|
if not os.path.exists(absolute_path):
|
||||||
valid_file_info = False
|
valid_file_info = False
|
||||||
log.warning(
|
log.warning(
|
||||||
@ -83,15 +106,7 @@ class ManifestParser(object):
|
|||||||
file,
|
file,
|
||||||
absolute_path
|
absolute_path
|
||||||
))
|
))
|
||||||
service_manifest_descr["valid"] = valid_file_info
|
service_manifest_data["valid"] = valid_file_info
|
||||||
|
|
||||||
manifests.append(Manifest(service_manifest_descr))
|
manifests.append(Manifest(service_manifest_data))
|
||||||
return manifests
|
return manifests
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
ManifestParser(os.path.join(os.path.dirname(__file__), 'Services')).parse()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
Loading…
x
Reference in New Issue
Block a user