Commit b0a8d3fd authored by Xiaowu Zhang's avatar Xiaowu Zhang

download: add shared feature

parent 06b80033
...@@ -28,6 +28,8 @@ import errno ...@@ -28,6 +28,8 @@ import errno
import os import os
import shutil import shutil
import zc.buildout import zc.buildout
import logging
from hashlib import md5
class Recipe(object): class Recipe(object):
_parts = None _parts = None
...@@ -38,17 +40,45 @@ class Recipe(object): ...@@ -38,17 +40,45 @@ class Recipe(object):
hash_name=True) hash_name=True)
self._url = options['url'] self._url = options['url']
self._md5sum = options.get('md5sum') self._md5sum = options.get('md5sum')
self._name = name
mode = options.get('mode') mode = options.get('mode')
log = logging.getLogger(name)
if mode is not None: if mode is not None:
mode = int(mode, 8) mode = int(mode, 8)
self._mode = mode self._mode = mode
if 'filename' in options and 'destination' in options: if 'filename' in options and 'destination' in options:
raise zc.buildout.UserError('Parameters filename and destination are ' raise zc.buildout.UserError('Parameters filename and destination are '
'exclusive.') 'exclusive.')
destination = options.get('destination', None) destination = options.get('destination', None)
if destination is None: if destination is None:
shared = options.get('shared')
self._shared = shared
if shared:
shared_part = buildout['buildout'].get('shared-part', None)
if not shared_part:
raise ValueError(
" Set ${buildout:shared-part} for shared feature")
shared = os.path.join(shared_part.strip().rstrip('/'), name)
if not os.path.exists(shared):
os.makedirs(shared)
self._debug_signature_text = []
m = md5()
profile_base_location = options.get('_profile_base_location_', '')
for k, v in sorted(options.items()):
if profile_base_location:
v = v.replace(profile_base_location, '${:_profile_base_location_}')
option_signature = ('%r: %r' % (k, v)).encode()
self._debug_signature_text.append(option_signature)
m.update(option_signature)
shared = os.path.join(shared, m.hexdigest())
self._parts = parts = shared
log.info('shared directory %s set for %s' % (shared, name))
else:
self._parts = parts = os.path.join(buildout_section['parts-directory'], self._parts = parts = os.path.join(buildout_section['parts-directory'],
name) name)
destination = os.path.join(parts, options.get('filename', name)) destination = os.path.join(parts, options.get('filename', name))
# Compatibility with other recipes: expose location # Compatibility with other recipes: expose location
options['location'] = parts options['location'] = parts
...@@ -58,6 +88,13 @@ class Recipe(object): ...@@ -58,6 +88,13 @@ class Recipe(object):
destination = self._destination destination = self._destination
result = [destination] result = [destination]
parts = self._parts parts = self._parts
log = logging.getLogger(self._name)
if self._shared:
log.info('Checking whether package is installed at shared path: %s' % destination)
if os.path.exists(destination):
log.info('This shared package has been installed by other package')
return []
if parts is not None and not os.path.isdir(parts): if parts is not None and not os.path.isdir(parts):
os.mkdir(parts) os.mkdir(parts)
result.append(parts) result.append(parts)
...@@ -74,6 +111,10 @@ class Recipe(object): ...@@ -74,6 +111,10 @@ class Recipe(object):
if self._mode is not None: if self._mode is not None:
os.fchmod(fdst.fileno(), self._mode) os.fchmod(fdst.fileno(), self._mode)
shutil.copyfileobj(fsrc, fdst) shutil.copyfileobj(fsrc, fdst)
if self._shared:
with open(os.path.join(parts, ".slapos.recipe.build.signature"), 'w') as f:
f.write('\n'.join(self._debug_signature_text))
return result return result
def update(self): def update(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment