Repository support for VR

VR structure changed to match repository one
Link templates dir to repositories

Change-Id: I18ba43ed4502b753127d6eca5dc01f84205312a9
This commit is contained in:
Jedrzej Nowak 2015-12-21 17:21:28 +01:00
parent abf0ffef3f
commit 594dde3114
21 changed files with 93 additions and 22 deletions

View File

@ -51,3 +51,4 @@
tasks:
- file: path=/var/lib/solar/repositories state=directory
- file: src=/vagrant/resources dest=/var/lib/solar/repositories/resources state=link
- file: src=/vagrant/templates dest=/var/lib/solar/repositories/templates state=link

View File

@ -134,8 +134,7 @@ def clear_all():
@resource.command()
@click.argument('name')
@click.argument(
'base_path', type=click.Path(exists=True, resolve_path=True))
@click.argument('base_path')
@click.argument('args', nargs=-1)
def create(args, base_path, name):
args_parsed = {}

View File

@ -17,12 +17,18 @@ from collections import defaultdict
import errno
import os
import re
import semver
import shutil
from enum import Enum
from solar import utils
RES_TYPE = Enum("Resource Types", 'Normal Virtual')
class RepositoryException(Exception):
pass
@ -66,22 +72,29 @@ class Repository(object):
def _list_source_contents(self, source):
for pth in os.listdir(source):
single_path = os.path.join(source, pth)
if os.path.exists(os.path.join(single_path, 'meta.yaml')):
yield pth, single_path
if pth.endswith('.yaml'):
pth = pth[:-5]
yield RES_TYPE.Virtual, pth, single_path
elif os.path.exists(os.path.join(single_path, 'meta.yaml')):
yield RES_TYPE.Normal, pth, single_path
else:
if not os.path.isdir(single_path):
continue
for single in os.listdir(single_path):
try:
semver.parse(single)
except ValueError:
if single.endswith('.yaml'):
fp = os.path.join(single_path, single)
raise RepositoryException("Invalid repository"
"content: %r" % fp)
yield RES_TYPE.Virtual, pth, fp
else:
fp = os.path.join(single_path, single)
if os.path.exists(os.path.join(fp, 'meta.yaml')):
yield pth, fp
try:
semver.parse(single)
except ValueError:
fp = os.path.join(single_path, single)
raise RepositoryException("Invalid repository"
"content: %r" % fp)
else:
fp = os.path.join(single_path, single)
if os.path.exists(os.path.join(fp, 'meta.yaml')):
yield RES_TYPE.Normal, pth, fp
@classmethod
def repo_path(cls, repo_name):
@ -105,8 +118,11 @@ class Repository(object):
def _add_contents(self, source, overwrite=False):
cnts = self._list_source_contents(source)
for single_name, single_path in cnts:
self.add_single(single_name, single_path, overwrite)
for res_type, single_name, single_path in cnts:
if res_type is RES_TYPE.Normal:
self.add_single(single_name, single_path, overwrite)
else:
self.add_single_vr(single_name, single_path, overwrite)
def add_single(self, name, source, overwrite=False):
try:
@ -129,6 +145,32 @@ class Repository(object):
shutil.rmtree(target_path)
shutil.copytree(source, target_path, symlinks=True)
def add_single_vr(self, name, source, overwrite=False):
# with open(source, 'rb') as f:
# parsed = yaml.safe_load(f.read())
# version = parsed.get('version', '1.0.0')
version = '1.0.0'
with open(source, 'rb') as f:
data = f.read()
regex = re.compile('^version.*\:(?P<version>.+)')
m = regex.search(data)
if m:
v_file = m.group("version")
if v_file:
version = v_file
target_dir = os.path.join(self.fpath, name, version)
target_path = os.path.join(target_dir, "{}.yaml".format(name))
os.makedirs(target_dir)
try:
shutil.copy(source, target_path)
except OSError as e:
if e.errno != errno.EEXIST:
raise
if not overwrite:
raise
shutil.rm(target_dir)
shutil.copy(source, target_path)
def remove(self):
shutil.rmtree(self.fpath)
@ -280,3 +322,11 @@ class Repository(object):
def parse(cls, spec):
spec = cls._parse_spec(spec)
return Repository(spec['repo']), spec
def is_virtual(self, spec):
return os.path.exists(self.get_virtual_path(spec))
def get_virtual_path(self, spec):
spec = self._parse_spec(spec)
p = self.get_path(spec)
return os.path.join(p, "{}.yaml".format(spec['resource_name']))

View File

@ -14,17 +14,19 @@
# under the License.
from collections import defaultdict
import os
from StringIO import StringIO
from jinja2 import Environment
from jinja2 import meta
import os
import yaml
from solar.core.log import log
from solar.core import provider
from solar.core.resource import load as load_resource
from solar.core.resource import load_by_tags
from solar.core.resource.repository import Repository
from solar.core.resource import Resource
from solar.events.api import add_event
from solar.events.controls import Dep
@ -45,8 +47,27 @@ def create(name, spec, args=None, tags=None, virtual_resource=None):
if isinstance(spec, provider.BaseProvider):
spec = spec.directory
if is_virtual(spec):
template = _compile_file(name, spec, args)
# fullpath
# TODO: (jnowak) find a better way to code this part
if spec.startswith('/'):
if os.path.isfile(spec):
template = _compile_file(name, spec, args)
yaml_template = yaml.load(StringIO(template))
rs = create_virtual_resource(name, yaml_template, tags)
else:
r = create_resource(name,
spec,
args=args,
tags=tags,
virtual_resource=virtual_resource)
rs = [r]
return rs
repo, parsed_spec = Repository.parse(spec)
if repo.is_virtual(spec):
path = repo.get_virtual_path(spec)
template = _compile_file(name, path, args)
yaml_template = yaml.load(StringIO(template))
rs = create_virtual_resource(name, yaml_template, tags)
else:
@ -126,10 +147,6 @@ def _get_template(name, content, kwargs, inputs):
return template
def is_virtual(path):
return os.path.isfile(path)
def create_resources(resources, tags=None):
created_resources = []
for r in resources:
@ -141,7 +158,11 @@ def create_resources(resources, tags=None):
tags = r.get('tags', [])
new_resources = create(resource_name, spec, args=args, tags=tags)
created_resources += new_resources
if not is_virtual(spec):
is_virtual = False
if not spec.startswith('/'):
repo, parsed_spec = Repository.parse(spec)
is_virtual = repo.is_virtual(spec)
if not is_virtual:
if node:
node = load_resource(node)
r = new_resources[0]