Repository support for VR
VR structure changed to match repository one Link templates dir to repositories Change-Id: I18ba43ed4502b753127d6eca5dc01f84205312a9
This commit is contained in:
parent
abf0ffef3f
commit
594dde3114
|
@ -51,3 +51,4 @@
|
||||||
tasks:
|
tasks:
|
||||||
- file: path=/var/lib/solar/repositories state=directory
|
- file: path=/var/lib/solar/repositories state=directory
|
||||||
- file: src=/vagrant/resources dest=/var/lib/solar/repositories/resources state=link
|
- file: src=/vagrant/resources dest=/var/lib/solar/repositories/resources state=link
|
||||||
|
- file: src=/vagrant/templates dest=/var/lib/solar/repositories/templates state=link
|
||||||
|
|
|
@ -134,8 +134,7 @@ def clear_all():
|
||||||
|
|
||||||
@resource.command()
|
@resource.command()
|
||||||
@click.argument('name')
|
@click.argument('name')
|
||||||
@click.argument(
|
@click.argument('base_path')
|
||||||
'base_path', type=click.Path(exists=True, resolve_path=True))
|
|
||||||
@click.argument('args', nargs=-1)
|
@click.argument('args', nargs=-1)
|
||||||
def create(args, base_path, name):
|
def create(args, base_path, name):
|
||||||
args_parsed = {}
|
args_parsed = {}
|
||||||
|
|
|
@ -17,12 +17,18 @@ from collections import defaultdict
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import semver
|
import semver
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
from solar import utils
|
from solar import utils
|
||||||
|
|
||||||
|
|
||||||
|
RES_TYPE = Enum("Resource Types", 'Normal Virtual')
|
||||||
|
|
||||||
|
|
||||||
class RepositoryException(Exception):
|
class RepositoryException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -66,22 +72,29 @@ class Repository(object):
|
||||||
def _list_source_contents(self, source):
|
def _list_source_contents(self, source):
|
||||||
for pth in os.listdir(source):
|
for pth in os.listdir(source):
|
||||||
single_path = os.path.join(source, pth)
|
single_path = os.path.join(source, pth)
|
||||||
if os.path.exists(os.path.join(single_path, 'meta.yaml')):
|
if pth.endswith('.yaml'):
|
||||||
yield pth, single_path
|
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:
|
else:
|
||||||
if not os.path.isdir(single_path):
|
if not os.path.isdir(single_path):
|
||||||
continue
|
continue
|
||||||
for single in os.listdir(single_path):
|
for single in os.listdir(single_path):
|
||||||
try:
|
if single.endswith('.yaml'):
|
||||||
semver.parse(single)
|
|
||||||
except ValueError:
|
|
||||||
fp = os.path.join(single_path, single)
|
fp = os.path.join(single_path, single)
|
||||||
raise RepositoryException("Invalid repository"
|
yield RES_TYPE.Virtual, pth, fp
|
||||||
"content: %r" % fp)
|
|
||||||
else:
|
else:
|
||||||
fp = os.path.join(single_path, single)
|
try:
|
||||||
if os.path.exists(os.path.join(fp, 'meta.yaml')):
|
semver.parse(single)
|
||||||
yield pth, fp
|
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
|
@classmethod
|
||||||
def repo_path(cls, repo_name):
|
def repo_path(cls, repo_name):
|
||||||
|
@ -105,8 +118,11 @@ class Repository(object):
|
||||||
|
|
||||||
def _add_contents(self, source, overwrite=False):
|
def _add_contents(self, source, overwrite=False):
|
||||||
cnts = self._list_source_contents(source)
|
cnts = self._list_source_contents(source)
|
||||||
for single_name, single_path in cnts:
|
for res_type, single_name, single_path in cnts:
|
||||||
self.add_single(single_name, single_path, overwrite)
|
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):
|
def add_single(self, name, source, overwrite=False):
|
||||||
try:
|
try:
|
||||||
|
@ -129,6 +145,32 @@ class Repository(object):
|
||||||
shutil.rmtree(target_path)
|
shutil.rmtree(target_path)
|
||||||
shutil.copytree(source, target_path, symlinks=True)
|
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):
|
def remove(self):
|
||||||
shutil.rmtree(self.fpath)
|
shutil.rmtree(self.fpath)
|
||||||
|
|
||||||
|
@ -280,3 +322,11 @@ class Repository(object):
|
||||||
def parse(cls, spec):
|
def parse(cls, spec):
|
||||||
spec = cls._parse_spec(spec)
|
spec = cls._parse_spec(spec)
|
||||||
return Repository(spec['repo']), 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']))
|
||||||
|
|
|
@ -14,17 +14,19 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import os
|
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
from jinja2 import Environment
|
from jinja2 import Environment
|
||||||
from jinja2 import meta
|
from jinja2 import meta
|
||||||
|
|
||||||
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from solar.core.log import log
|
from solar.core.log import log
|
||||||
from solar.core import provider
|
from solar.core import provider
|
||||||
from solar.core.resource import load as load_resource
|
from solar.core.resource import load as load_resource
|
||||||
from solar.core.resource import load_by_tags
|
from solar.core.resource import load_by_tags
|
||||||
|
from solar.core.resource.repository import Repository
|
||||||
from solar.core.resource import Resource
|
from solar.core.resource import Resource
|
||||||
from solar.events.api import add_event
|
from solar.events.api import add_event
|
||||||
from solar.events.controls import Dep
|
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):
|
if isinstance(spec, provider.BaseProvider):
|
||||||
spec = spec.directory
|
spec = spec.directory
|
||||||
|
|
||||||
if is_virtual(spec):
|
# fullpath
|
||||||
template = _compile_file(name, spec, args)
|
# 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))
|
yaml_template = yaml.load(StringIO(template))
|
||||||
rs = create_virtual_resource(name, yaml_template, tags)
|
rs = create_virtual_resource(name, yaml_template, tags)
|
||||||
else:
|
else:
|
||||||
|
@ -126,10 +147,6 @@ def _get_template(name, content, kwargs, inputs):
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
|
||||||
def is_virtual(path):
|
|
||||||
return os.path.isfile(path)
|
|
||||||
|
|
||||||
|
|
||||||
def create_resources(resources, tags=None):
|
def create_resources(resources, tags=None):
|
||||||
created_resources = []
|
created_resources = []
|
||||||
for r in resources:
|
for r in resources:
|
||||||
|
@ -141,7 +158,11 @@ def create_resources(resources, tags=None):
|
||||||
tags = r.get('tags', [])
|
tags = r.get('tags', [])
|
||||||
new_resources = create(resource_name, spec, args=args, tags=tags)
|
new_resources = create(resource_name, spec, args=args, tags=tags)
|
||||||
created_resources += new_resources
|
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:
|
if node:
|
||||||
node = load_resource(node)
|
node = load_resource(node)
|
||||||
r = new_resources[0]
|
r = new_resources[0]
|
||||||
|
|
Loading…
Reference in New Issue