Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar_network
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2014-02-25 10:47:27 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2014-02-25 10:47:27 (GMT)
commit7552454f28decea7fae01af1a6d4d4faa173bf88 (patch)
tree87920e0c97bde2fa4d4989705e98915641337d84 /sugar_network
parent4dc349755c8463c8a197433126c78988c74a1b43 (diff)
Remove more ZI remains
* one command per context; * exact dependency comparing.
Diffstat (limited to 'sugar_network')
-rw-r--r--sugar_network/model/__init__.py26
-rw-r--r--sugar_network/node/model.py37
-rw-r--r--sugar_network/node/routes.py5
-rw-r--r--sugar_network/toolkit/spec.py135
4 files changed, 60 insertions, 143 deletions
diff --git a/sugar_network/model/__init__.py b/sugar_network/model/__init__.py
index f7be261..5b7a245 100644
--- a/sugar_network/model/__init__.py
+++ b/sugar_network/model/__init__.py
@@ -83,15 +83,15 @@ class Release(object):
__, release = load_bundle(
blobs.post(release, this.request.content_type),
context=this.request.guid)
- return release['spec']['*-*']['bundle'], release
+ return release['bundles']['*-*']['blob'], release
def teardown(self, release):
if this.resource.exists and \
'activity' not in this.resource['type'] and \
'book' not in this.resource['type']:
return
- for spec in release['spec'].values():
- blobs.delete(spec['bundle'])
+ for bundle in release['bundles'].values():
+ blobs.delete(bundle['blob'])
def encode(self, value):
return []
@@ -147,9 +147,11 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
release['license'] = this.request['license']
if isinstance(release['license'], basestring):
release['license'] = [release['license']]
- release['spec'] = {'*-*': {
- 'bundle': blob.digest,
- }}
+ release['bundles'] = {
+ '*-*': {
+ 'bundle': blob.digest,
+ },
+ }
else:
context_type = 'activity'
unpack_size = 0
@@ -177,12 +179,14 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
release['stability'] = spec['stability']
if spec['license'] is not EMPTY_LICENSE:
release['license'] = spec['license']
- release['commands'] = spec.commands
+ release['command'] = spec.command
release['requires'] = spec.requires
- release['spec'] = {'*-*': {
- 'bundle': blob.digest,
- }}
- release['unpack_size'] = unpack_size
+ release['bundles'] = {
+ '*-*': {
+ 'blob': blob.digest,
+ 'unpack_size': unpack_size,
+ },
+ }
blob['content-type'] = 'application/vnd.olpc-sugar'
enforce(context, http.BadRequest, 'Context is not specified')
diff --git a/sugar_network/node/model.py b/sugar_network/node/model.py
index 7276b75..9ead01c 100644
--- a/sugar_network/node/model.py
+++ b/sugar_network/node/model.py
@@ -176,7 +176,7 @@ def solve(volume, top_context, lsb_id=None, lsb_release=None,
top_stability = stability or ['stable']
if isinstance(top_stability, basestring):
top_stability = [top_stability]
- top_cond = None
+ top_cond = []
top_requires = {}
if isinstance(requires, basestring):
top_requires.update(spec.parse_requires(requires))
@@ -196,15 +196,6 @@ def solve(volume, top_context, lsb_id=None, lsb_release=None,
_logger.debug('Solve %r lsb_id=%r lsb_release=%r stability=%r requires=%r',
top_context.guid, lsb_id, lsb_release, top_stability, top_requires)
- def ensure_version(version, cond):
- if not cond:
- return True
- for not_before, before in cond['restrictions']:
- if before is not None and version >= before or \
- not_before is not None and version < not_before:
- return False
- return True
-
def rate_release(digest, release):
return [_STABILITY_RATES.get(release['stability']) or 0,
release['version'],
@@ -217,7 +208,7 @@ def solve(volume, top_context, lsb_id=None, lsb_release=None,
for dep, cond in deps.items():
dep_clause = [-v_usage]
for v_release in add_context(dep):
- if ensure_version(varset[v_release][0], cond):
+ if spec.ensure(varset[v_release][1]['version'], cond):
dep_clause.append(v_release)
clauses.append(dep_clause)
@@ -242,7 +233,10 @@ def solve(volume, top_context, lsb_id=None, lsb_release=None,
pkg_lst = alias.get('binary', []) + alias.get('devel', [])
if pkg_lst:
clause.append(len(varset))
- varset.append((pkg_ver, 'packages', {context.guid: pkg_lst}))
+ varset.append((
+ context.guid,
+ {'version': pkg_ver, 'packages': pkg_lst},
+ ))
else:
candidates = []
for digest, release in releases.items():
@@ -251,18 +245,17 @@ def solve(volume, top_context, lsb_id=None, lsb_release=None,
release = release['value']
if release['stability'] not in top_stability or \
context.guid == top_context.guid and \
- not ensure_version(release['version'], top_cond):
+ not spec.ensure(release['version'], top_cond):
continue
bisect.insort(candidates, rate_release(digest, release))
for release in reversed(candidates):
digest = release[-1]
release = releases[digest]['value']
+ release_info = {'version': release['version'], 'blob': digest}
+ if context.guid == top_context.guid:
+ release_info['command'] = release['command']
v_release = len(varset)
- varset.append((
- release['version'],
- 'files',
- {context.guid: digest},
- ))
+ varset.append((context.guid, release_info))
clause.append(v_release)
add_deps(context, v_release, release.get('requires') or {})
@@ -283,13 +276,7 @@ def solve(volume, top_context, lsb_id=None, lsb_release=None,
if not top_context.guid in result:
_logger.debug('No top versions for %r', top_context.guid)
return None
-
- solution = {'files': {}, 'packages': {}}
- for v in result.values():
- __, key, items = varset[v]
- solution[key].update(items)
- top_release = top_context['releases'][solution['files'][top_context.guid]]
- solution['commands'] = top_release['value']['commands']
+ solution = dict([varset[i] for i in result.values()])
_logger.debug('Solution for %r: %r', top_context.guid, solution)
diff --git a/sugar_network/node/routes.py b/sugar_network/node/routes.py
index 66b7823..6d5d200 100644
--- a/sugar_network/node/routes.py
+++ b/sugar_network/node/routes.py
@@ -27,8 +27,7 @@ from sugar_network.node import stats_user, model
# pylint: disable-msg=W0611
from sugar_network.toolkit.router import route, preroute, postroute, ACL
from sugar_network.toolkit.router import Unauthorized, Request, fallbackroute
-from sugar_network.toolkit.spec import parse_requires, ensure_requires
-from sugar_network.toolkit.spec import parse_version
+from sugar_network.toolkit.spec import parse_requires, parse_version
from sugar_network.toolkit.bundle import Bundle
from sugar_network.toolkit.coroutine import this
from sugar_network.toolkit import pylru, http, coroutine, exception, enforce
@@ -157,7 +156,7 @@ class NodeRoutes(db.Routes, FrontRoutes):
arguments={'requires': list})
def get_clone(self, request, response):
solution = self.solve(request)
- return blobs.get(solution['files'][request.guid])
+ return blobs.get(solution[request.guid]['blob'])
@route('GET', ['user', None], cmd='stats-info',
mime_type='application/json', acl=ACL.AUTH)
diff --git a/sugar_network/toolkit/spec.py b/sugar_network/toolkit/spec.py
index 78c6007..a8489ce 100644
--- a/sugar_network/toolkit/spec.py
+++ b/sugar_network/toolkit/spec.py
@@ -15,7 +15,6 @@
import re
import os
-import sys
import logging
from os.path import join, exists, dirname
from ConfigParser import ConfigParser
@@ -45,7 +44,7 @@ _STABILITIES = ('insecure', 'buggy', 'developer', 'testing', 'stable')
_POLICY_URL = 'http://wiki.sugarlabs.org/go/Sugar_Network/Policy'
_LIST_SEPARATOR = ','
-_RESTRICTION_RE = re.compile('(<|<=|=|>|>=)\\s*([0-9.]+)')
+_RESTRICTION_RE = re.compile('(<|<=|=|==|>|>=)\\s*([0-9.]+)')
_VERSION_RE = re.compile('-([a-z]*)')
_VERSION_MOD_TO_VALUE = {
@@ -146,89 +145,47 @@ def format_version(version):
return ''.join(version)
-def format_next_version(version, deep=True):
- """Convert incremented version to string representation.
-
- Before convertation, the last version's rank will be incremented.
- If string value is passed, it will be parsed to procuduce
- canonicalized string representation.
-
- """
- if version is None:
- return None
- if isinstance(version, basestring):
- version = parse_version(version)
- if deep:
- version[-2] += [1]
- else:
- version[-2][-1] += 1
- return format_version(version)
-
-
def parse_requires(requires):
result = {}
for dep_str in _parse_list(requires):
- dep = _Dependency()
-
- if dep_str.startswith('[') and dep_str.endswith(']'):
- dep_str = dep_str[1:-1]
- dep['importance'] = 'recommended'
-
parts = _RESTRICTION_RE.split(dep_str)
- enforce(parts[0], 'Can parse dependency from "%s" string', dep_str)
-
+ enforce(parts[0], 'Cannot parse %r dependency', dep_str)
dep_name = parts.pop(0).strip()
- if dep_name in result:
- result[dep_name].update(dep)
- dep = result[dep_name]
- else:
- result[dep_name] = dep
+ dep = result.setdefault(dep_name, [])
- not_before = None
- before = None
while len(parts) >= 3:
- if parts[0] == '<':
- before = format_version(parts[1])
- elif parts[0] == '<=':
- before = format_next_version(parts[1], False)
- elif parts[0] == '>':
- not_before = format_next_version(parts[1], False)
- elif parts[0] == '>=':
- not_before = format_version(parts[1])
- elif parts[0] == '=':
- not_before = format_version(parts[1])
- before = format_next_version(parts[1], False)
+ rel = parts[0]
+ if rel in ('=', '=='):
+ rel = [0]
+ elif rel == '<':
+ rel = [-1]
+ elif rel == '>':
+ rel = [1]
+ elif rel == '<=':
+ rel = [-1, 0]
+ elif rel == '>=':
+ rel = [1, 0]
+ dep.append((rel, parse_version(parts[1])))
del parts[:3]
enforce(not parts or not parts[0].strip(),
- 'Cannot parse "%s", it should be in format '
- '"<dependency> (>=|<|=) <version>"', dep_str)
-
- if before or not_before:
- dep.setdefault('restrictions', [])
- dep['restrictions'].append((not_before, before))
+ 'Cannot parse %r dependency', dep_str)
return result
-def ensure_requires(to_consider, to_apply):
-
- def intersect(x, y):
- l = max([parse_version(i) for i, __ in (x + y)])
- r = min([[[sys.maxint]] if i is None else parse_version(i)
- for __, i in (x + y)])
- return l is None or r is None or l < r
-
- for name, cond in to_apply.items():
- dep = to_consider.get(name)
- if dep is None:
- return False
- if 'restrictions' not in dep or 'restrictions' not in cond:
- continue
- if not intersect(dep['restrictions'], cond['restrictions']):
- return False
-
+def ensure(version, cond):
+ if cond:
+ for op, cond_version in cond:
+ if op == [0]:
+ # Make `version` the same length as `cond_version`
+ if len(version) > len(cond_version):
+ version = version[:len(cond_version) - 1] + [0]
+ if len(version[0]) > len(cond_version[0]):
+ version = [version[0][:len(cond_version[0])], 0]
+ if cmp(version, cond_version) not in op:
+ return False
return True
@@ -236,7 +193,7 @@ class Spec(object):
def __init__(self, spec=None, root=None):
self.path = None
- self.commands = {}
+ self.command = None
self.bindings = set()
self.requires = {}
self.build_requires = []
@@ -391,14 +348,12 @@ class Spec(object):
i.name = '-'.join(i.section.split(':')[1:])
def _new_command(self, section, requires, name):
+ enforce(self.command is None, 'Only one command is allowed')
cmdline = self._get(section, 'exec')
enforce(cmdline,
'Option "exec" should exist for [%s] section', section)
- command = self.commands[name] = _Command(name, cmdline)
- if ':' in section:
- command.requires.update(requires)
- else:
- self.requires.update(requires)
+ self.command = cmdline
+ self.requires.update(requires)
def _new_activity(self, section, requires):
enforce(':' not in section, '[Activity] should be singular')
@@ -476,34 +431,6 @@ class _Library(_Section):
pass
-class _Command(dict):
-
- def __init__(self, name, cmdline):
- dict.__init__(self)
- self['exec'] = cmdline
- self.name = name
- self.requires = {}
-
-
-class _Dependency(dict):
-
- def versions_range(self):
- for not_before, before in self.get('restrictions') or []:
- if not_before is None:
- continue
- i = parse_version(not_before)[0]
- yield format_version([i, 0])
- if before is None:
- continue
- end = parse_version(before)[0]
- i = i[:min(len(i), len(end))]
- while True:
- i[-1] += 1
- if i >= end:
- break
- yield format_version([i, 0])
-
-
def _parse_bindings(text):
result = set()