def convert_passwords(path, val): log.info("Converting %s", path) password = str(path)[len("passwords."):] configuration.converters.started(path) environment = configuration['bespin'].environment val_as_dict = configuration["passwords"][password].as_dict() if not environment: raise BespinError("No environment was provided", available=list( configuration["environments"].keys())) password_environment_as_dict = {} if ["passwords", password, environment] in configuration: password_environment_as_dict = configuration[[ "passwords", password, environment ]].as_dict() base = MergedOptions(dont_prefix=path.configuration.dont_prefix, converters=path.configuration.converters) everything = path.configuration.root().wrapped() base.update(val_as_dict) everything[path] = val_as_dict base.update(password_environment_as_dict) everything[path].update(password_environment_as_dict) for thing in (base, everything): thing["__password__"] = val thing["__environment__"] = configuration["environments"][ environment] meta = Meta(everything, [("passwords", ""), (password, "")]) return bespin_spec.password_spec.normalise(meta, base)
def convert_passwords(path, val): log.info("Converting %s", path) password = str(path)[len("passwords."):] configuration.converters.started(path) environment = configuration['bespin'].environment val_as_dict = configuration["passwords"][password].as_dict() if not environment: raise BespinError("No environment was provided", available=list(configuration["environments"].keys())) password_environment_as_dict = {} if ["passwords", password, environment] in configuration: password_environment_as_dict = configuration["passwords", password, environment].as_dict() base = MergedOptions(dont_prefix=path.configuration.dont_prefix, converters=path.configuration.converters) everything = path.configuration.root().wrapped() base.update(val_as_dict) everything[path] = val_as_dict base.update(password_environment_as_dict) everything[path].update(password_environment_as_dict) for thing in (base, everything): thing["__password__"] = val thing["__environment__"] = configuration["environments"][environment] meta = Meta(everything, [("passwords", ""), (password, "")]) return bespin_spec.password_spec.normalise(meta, base)
class StackResolver(object): def __init__(self): self.registered = MergedOptions() def register(self, stack_kls, extra_aliases=None): """Register a stack type""" aliases = list(getattr(stack_kls, "aliases", [])) if extra_aliases: aliases.extend(extra_aliases) if not aliases: raise BadStackKls("No alias provided", kls=stack_kls) self.registered.update({alias: stack_kls for alias in aliases}) def register_import(self, import_line, extra_aliases=None): """Register a kls from an import string""" if ":" not in import_line: raise BadImport("Expecting '<path>:<obj>'", got=import_line) path, obj = import_line.split(":") if not valid_python_path(path): raise BadImport("Path portion of import is not a valid python name", path=path) if not valid_python_name(obj): raise BadImport("obj portion of import is not a valid python name", obj=obj) obj = do_import(path, obj) self.register(obj, extra_aliases) def register_defaults(self): self.register_import("cloudcity.resolution.types.config:ConfigStack") def resolve(self, name, options): the_type = options.get("type", "config") if the_type not in self.registered: raise UnknownStackType(name=name, only_have=self.registered.keys(), wanted=the_type) return self.registered[the_type](name, options)
def resolve(self, options, resolve_order): """Go through and re-add parts of the options as according to global.resolve_order""" new_options = MergedOptions.using({"global": options.get("global", {})}) for key in options.keys(): new_values = MergedOptions() current_values = options[key] if current_values.get("no_resolve", False): new_values.update(current_values) else: for part in resolve_order: if not part: new_values.update(current_values) else: val = current_values.get(part) if val: new_values.update(val) new_options[key] = new_values new_options["global"]["resolve_order"] = resolve_order return new_options
def collect_configuration(self, configuration_file): """Return us a MergedOptions with this configuration and any collected configurations""" errors = [] result = self.read_yaml(configuration_file) configuration_dir = os.path.dirname( os.path.abspath(configuration_file)) images_from = [] images_from_path = None if "images" in result and "__images_from__" in result["images"]: images_from_path = result["images"]["__images_from__"] if not images_from_path.startswith("/"): images_from_path = os.path.join(configuration_dir, images_from_path) if not os.path.exists(images_from_path) or not os.path.isdir( images_from_path): raise BadConfiguration( "Specified folder for other configuration files points to a folder that doesn't exist", path="images.__images_from__", value=images_from_path) images_from = sorted( chain.from_iterable([[ os.path.join(root, fle) for fle in files if fle.endswith(".yml") or fle.endswith(".yaml") ] for root, dirs, files in os.walk(images_from_path)])) harpoon_spec = HarpoonSpec() configuration = MergedOptions(dont_prefix=[dictobj]) home_dir_configuration = self.home_dir_configuration_location() sources = [home_dir_configuration, configuration_file] + images_from def make_mtime_func(source): """Lazily calculate the mtime to avoid wasted computation""" return lambda: self.get_committime_or_mtime(source) for source in sources: if source is None or not os.path.exists(source): continue try: result = self.read_yaml(source) except BadYaml as error: errors.append(error) continue if "images" in result and "__images_from__" in result["images"]: del result["images"]["__images_from__"] if source in images_from: result = { "images": { os.path.splitext(os.path.basename(source))[0]: result } } result["mtime"] = make_mtime_func(source) if "images" in result: images = result.pop("images") images = dict( (image, MergedOptions.using(configuration.root(), val, converters=configuration.converters, source=source)) for image, val in images.items()) result["images"] = images configuration.update(result, dont_prefix=[dictobj], source=source) for image in result.get('images', {}).keys(): self.make_image_converters(image, configuration, harpoon_spec) def convert_harpoon(path, val): log.info("Converting %s", path) meta = Meta(path.configuration, [("harpoon", "")]) configuration.converters.started(path) return harpoon_spec.harpoon_spec.normalise(meta, val) harpoon_converter = Converter(convert=convert_harpoon, convert_path=["harpoon"]) configuration.add_converter(harpoon_converter) if errors: raise BadConfiguration("Some of the configuration was broken", _errors=errors) return configuration
def prepare(self, npm_deps, compiled_static_folder): ctxt = docker_context() harpoon_options = { "docker_context": ctxt , "no_intervention": True , "docker_context_maker": docker_context } self.harpoon = HarpoonSpec().harpoon_spec.normalise(Meta({}, []), harpoon_options) config_root = pkg_resources.resource_filename(__package__, "") deps = self.default_npm_deps() deps.update(npm_deps) image_name = "dashmat-jsx-builder" everything = MergedOptions(dont_prefix=[dictobj]) everything.update( { "harpoon": self.harpoon , "config_root": config_root , "images": { image_name: { "harpoon": self.harpoon , "configuration": everything , "volumes": { "mount": [ [ compiled_static_folder, "/compiled" ] ] } , "context": { "enabled" : False } , "persistence": { "action": "npm install && npm dedup" , "folders": ["/project/node_modules", "/usr/lib/node_modules"] } , "commands": [ "FROM gliderlabs/alpine:3.2" , "RUN apk-install bash nodejs" , "RUN npm install -g npm" , "RUN mkdir /project" , "WORKDIR /project" , [ "ADD" , { "dest": "/project/package.json" , "content": json.dumps( { "name": "dashmat" , "version": "0.1.0" , "dependencies": collections.OrderedDict(sorted(deps.items())) } , sort_keys=True ) , "mtime": mtime } ] ] } } } ) def convert_image(path, val): meta = Meta(everything, [(part, "") for part in path.path]) return HarpoonSpec().image_spec.normalise(meta, val) everything.add_converter(Converter(convert=convert_image, convert_path=["images", image_name])) everything.converters.activate() self.image = everything[["images", image_name]] Builder().make_image(self.image, {self.image.name: self.image})
def collect_configuration(self, configuration_file): """Return us a MergedOptions with this configuration and any collected configurations""" errors = [] result = self.read_yaml(configuration_file) configuration_dir = os.path.dirname(os.path.abspath(configuration_file)) images_from = [] images_from_path = None if "images" in result and "__images_from__" in result["images"]: images_from_path = result["images"]["__images_from__"] if not images_from_path.startswith("/"): images_from_path = os.path.join(configuration_dir, images_from_path) if not os.path.exists(images_from_path) or not os.path.isdir(images_from_path): raise BadConfiguration("Specified folder for other configuration files points to a folder that doesn't exist", path="images.__images_from__", value=images_from_path) images_from = sorted(chain.from_iterable([ [os.path.join(root, fle) for fle in files if fle.endswith(".yml") or fle.endswith(".yaml")] for root, dirs, files in os.walk(images_from_path) ])) harpoon_spec = HarpoonSpec() configuration = MergedOptions(dont_prefix=[dictobj]) home_dir_configuration = self.home_dir_configuration_location() sources = [home_dir_configuration, configuration_file] + images_from def make_mtime_func(source): """Lazily calculate the mtime to avoid wasted computation""" return lambda: self.get_committime_or_mtime(source) for source in sources: if source is None or not os.path.exists(source): continue try: result = self.read_yaml(source) except BadYaml as error: errors.append(error) continue if "images" in result and "__images_from__" in result["images"]: del result["images"]["__images_from__"] if source in images_from: result = {"images": {os.path.splitext(os.path.basename(source))[0]: result}} result["mtime"] = make_mtime_func(source) if "images" in result: images = result.pop("images") images = dict( (image, MergedOptions.using(configuration.root(), val, converters=configuration.converters, source=source)) for image, val in images.items() ) result["images"] = images configuration.update(result, dont_prefix=[dictobj], source=source) for image in result.get('images', {}).keys(): self.make_image_converters(image, configuration, harpoon_spec) def convert_harpoon(path, val): log.info("Converting %s", path) meta = Meta(path.configuration, [("harpoon", "")]) configuration.converters.started(path) return harpoon_spec.harpoon_spec.normalise(meta, val) harpoon_converter = Converter(convert=convert_harpoon, convert_path=["harpoon"]) configuration.add_converter(harpoon_converter) if errors: raise BadConfiguration("Some of the configuration was broken", _errors=errors) return configuration