tripleo-common/tripleo_common/image/base.py

95 lines
3.6 KiB
Python

# Copyright 2015 Red Hat, 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 collections
import json
import os
import yaml
from oslo_log import log
from tripleo_common.image.exception import ImageSpecificationException
class BaseImageManager(object):
logger = log.getLogger(__name__ + '.BaseImageManager')
APPEND_ATTRIBUTES = ['elements', 'options', 'packages']
CONFIG_SECTIONS = (
DISK_IMAGES, UPLOADS, CONTAINER_IMAGES,
CONTAINER_IMAGES_TEMPLATE
) = (
'disk_images', 'uploads', 'container_images',
'container_images_template'
)
def __init__(self, config_files, images=None):
self.config_files = config_files
self.images = images
def _extend_or_set_attribute(self, existing_image, image, attribute_name):
attribute = image.get(attribute_name)
if attribute:
try:
existing_image[attribute_name].update(attribute)
except AttributeError:
existing_image[attribute_name].extend(attribute)
except KeyError:
existing_image[attribute_name] = attribute
def load_config_files(self, section):
config_data = collections.OrderedDict()
for config_file in self.config_files:
if os.path.isfile(config_file):
with open(config_file) as cf:
data = yaml.safe_load(cf.read()).get(section)
if not data:
return None
self.logger.debug('%s JSON: %s' % (section, str(data)))
for item in data:
image_name = item.get('imagename')
if image_name is None:
msg = 'imagename is required'
self.logger.error(msg)
raise ImageSpecificationException(msg)
if self.images is not None and \
image_name not in self.images:
self.logger.debug('Image %s ignored' % image_name)
continue
existing_image = config_data.get(image_name)
if not existing_image:
config_data[image_name] = item
continue
for attr in self.APPEND_ATTRIBUTES:
self._extend_or_set_attribute(existing_image, item,
attr)
# If a new key is introduced, add it.
for key, value in item.items():
if key not in existing_image:
existing_image[key] = item[key]
config_data[image_name] = existing_image
else:
self.logger.error('No config file exists at: %s' % config_file)
raise IOError('No config file exists at: %s' % config_file)
return [x for x in config_data.values()]
def json_output(self):
self.logger.info('Using config files: %s' % self.config_files)
disk_images = self.load_config_files(self.DISK_IMAGES)
print(json.dumps(disk_images))