Commit d8de6e80 authored by Xiaowu Zhang's avatar Xiaowu Zhang

Reimplement shared features

shared is path or True
if shared is True, use download-cache for path
parent aa5a651b
......@@ -26,25 +26,14 @@ Supported options
``--prefix`` injection takes place. You can also set the ``--prefix``
parameter explicitly in ``configure-options``.
``share``
``shared``
Specify the path in which this package is shared by many other
packages. When it's unset or blank, it means the package isn't
shared. Otherwise, it shared by many packages. Recipe will return
an empty list so that buildout will not uninstall the package when
uninstalling part.
In share mode, ``promises`` should be set so that recipe can tell
whether the package is installed. Otherwise nohting to do.
If ``share`` is not empty, ``location`` will be set to value of
``share``, and remove trailing '/'. So in case ``share`` is '/',
``location`` will be set to blank. Thus any reference like
"${part:location}/bin" in other parts will get the correct value.
This option is experiment now. Recipe doesn't try to set prefix
with the valule of this opton in the configure or make command,
you should specify them accordingly by yourself.
packages.
There has 2 use cases:
1. It's set to a path
2. It's set to True and download cache is a path
The package will be installed on path/shared/hash of options.
``md5sum``
......@@ -1019,10 +1008,16 @@ Look, "package" is reinstalled either:
building package
installing package
Install share package
Install shared package
=====================
Use option ``share`` to install a share pacakge.
Use option ``shared`` to install a shared pacakge.
>>> import os.path
>>> shared_dir = os.path.dirname(__file__)
>>> _ = system('rm -rf %s' % join(shared_dir, 'shared'))
If no download-cache is set, and shared is not a directory, an error is raised:
>>> write('buildout.cfg',
... """
... [buildout]
......@@ -1032,42 +1027,111 @@ Use option ``share`` to install a share pacakge.
... [package]
... recipe = slapos.recipe.cmmi
... url = file://%s/package-0.0.0.tar.gz
... share = /usr/local
... promises = ${:share}/bin/mypackage.exe
... """ % (src,))
... shared = True
... """% src)
>>> print system(buildout) #doctest:+ELLIPSIS
While:
Installing.
Getting section package.
Initializing section package.
...
ValueError: Set the 'shared' option of slapos.recipe.cmmi to an existing directory, or set ${buildout:download-cache}
>>> print system(buildout)
If download-cache is set and shared is True, package will be installed in download-cache/shared/a hash of the recipe's configuration options
>>> write('buildout.cfg',
... """
... [buildout]
... newest = false
... parts = package
... download-cache = %s
...
... [package]
... recipe = slapos.recipe.cmmi
... url = file://%s/package-0.0.0.tar.gz
... shared = True
... """ % (shared_dir, src))
>>> print system(buildout) #doctest:+ELLIPSIS
package: download cache directory .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/68cc2396fae62c7a9fad281b967f313c set for package
Uninstalling package.
Uninstalling package-2.
Installing package.
package: Checking whether package is installed at share path: /usr/local
package: could not find promise "/usr/local/bin/mypackage.exe"
package: [ENV] TMP = /sample_buildout/parts/package/tmp
configure --prefix=/usr/local
package: Checking whether package is installed at shared path: .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/68cc2396fae62c7a9fad281b967f313c
package: [ENV] TMP = .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/68cc2396fae62c7a9fad281b967f313c/tmp
configure --prefix=.../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/68cc2396fae62c7a9fad281b967f313c
building package
installing package
package: could not find promise "/usr/local/bin/mypackage.exe"
Do nothing if one package has been installed.
If shared and download-cache are set to 2 different location, package will be installed in shared_location/shared/a hash of the recipe's configuration options
>>> _ = system('rm -rf %s' % join(shared_dir, 'shared'))
>>> write('buildout.cfg',
... """
... [buildout]
... newest = false
... parts = package
... download-cache = /XXXXX/
...
... [package]
... recipe = slapos.recipe.cmmi
... url = file://%s/package-0.0.0.tar.gz
... share = /usr/local/bin
... promises =
... """ % (src,))
... shared = %s
... """ % (src, shared_dir))
>>> print system(buildout)
>>> print system(buildout) #doctest:+ELLIPSIS
package: download cache directory .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/59a2b0f2f9d5d62ddc81ced2b16cc3a6 set for package
Uninstalling package.
Installing package.
package: Checking whether package is installed at share path: /usr/local/bin
package: Checking whether package is installed at shared path: .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/59a2b0f2f9d5d62ddc81ced2b16cc3a6
package: [ENV] TMP = .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/59a2b0f2f9d5d62ddc81ced2b16cc3a6/tmp
configure --prefix=.../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/59a2b0f2f9d5d62ddc81ced2b16cc3a6
building package
installing package
Do nothing if one package has been installed.
>>> remove('.installed.cfg')
>>> write('buildout.cfg',
... """
... [buildout]
... newest = false
... parts = package
...
... [package]
... recipe = slapos.recipe.cmmi
... url = file://%s/package-0.0.0.tar.gz
... shared = %s
... """ % (src, shared_dir))
>>> print system(buildout) #doctest:+ELLIPSIS
package: download cache directory .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/59a2b0f2f9d5d62ddc81ced2b16cc3a6 set for package
Installing package.
package: Checking whether package is installed at shared path: .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/59a2b0f2f9d5d62ddc81ced2b16cc3a6
package: This shared package has been installed by other package
If options change, reinstall in different location:
>>> write('buildout.cfg',
... """
... [buildout]
... newest = false
... parts = package
...
... [package]
... recipe = slapos.recipe.cmmi
... url = file://%s/package-0.0.0.tar.gz
... shared = %s
... change = True
... """ % (src, shared_dir))
>>> print system(buildout) #doctest:+ELLIPSIS
package: download cache directory .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/a70df36830ef6cd53abe3e4fb8789d20 set for package
Uninstalling package.
Installing package.
package: Checking whether package is installed at shared path: .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/a70df36830ef6cd53abe3e4fb8789d20
package: [ENV] TMP = .../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/a70df36830ef6cd53abe3e4fb8789d20/tmp
configure --prefix=.../slapos.recipe.cmmi/slapos/recipe/cmmi/shared/package/a70df36830ef6cd53abe3e4fb8789d20
building package
installing package
For even more specific needs you can write your own recipe that uses
``slapos.recipe.cmmi`` and set the ``keep-compile-dir`` option to ``true``.
You can then continue from where this recipe finished by reading the location
......
......@@ -29,7 +29,7 @@ class Recipe(object):
self.options = options
self.buildout = buildout
self.name = name
log = logging.getLogger(self.name)
# Merge options if there is a matched platform section
platform_options = self.buildout.get(
"%s:%s:%s" % (name, sys.platform, self.get_machine()),
......@@ -40,12 +40,34 @@ class Recipe(object):
self.original_options = options.copy()
options.update(platform_options)
options['share'] = options.get('share', '').strip()
shared = options.get('shared', '')
if shared:
# If shard is not a path
# use default one
if not os.path.isdir(shared):
# Check if provide default location in buildout
shared = buildout['buildout'].get('download-cache', None)
if not shared:
raise ValueError(
" Set the 'shared' option of slapos.recipe.cmmi"
" to an existing"
" directory, or set ${buildout:download-cache}")
shared = shared.strip().rstrip('/')
shared = os.path.join(shared, 'shared', self.name)
# create shared dir if not exist
if not os.path.exists(shared):
os.makedirs(shared)
m = md5()
for k, v in sorted(options.items()):
m.update(('%r: %r' % (k, v)).encode())
shared = os.path.join(shared, m.hexdigest())
log.info('download cache directory %s set for %s' % (shared, self.name))
options['shared'] = shared
options['default-location'] = os.path.join(
buildout['buildout']['parts-directory'],
self.name)
share = options['share']
options['location'] = options['default-location'] if share == '' else share.rstrip('/')
self.name) if shared == '' else shared
options['location'] = options['default-location'] if shared == '' else shared
prefix = options.get('prefix', '').strip()
if prefix == '':
......@@ -250,10 +272,10 @@ class Recipe(object):
log = logging.getLogger(self.name)
parts = []
# In share mode, do nothing if package has been installed.
if (not self.options['share'] == ''):
log.info('Checking whether package is installed at share path: %s' % self.options['share'])
if self.check_promises(log):
# In shared mode, do nothing if package has been installed.
if (not self.options['shared'] == ''):
log.info('Checking whether package is installed at shared path: %s' % self.options['shared'])
if os.path.exists(self.options['shared']):
log.info('This shared package has been installed by other package')
return parts
......@@ -369,7 +391,7 @@ class Recipe(object):
log.info('Executing post-install')
self.run(post_install_cmd)
if (self.buildout_prefix != ''
and self.options['share'] == ''
and self.options['shared'] == ''
and os.path.exists(self.buildout_prefix)):
log.info('Getting installed file lists')
parts.extend(self.get_installed_files(tmp_path))
......@@ -395,7 +417,7 @@ class Recipe(object):
shutil.rmtree(compile_dir)
del self.options['compile-directory']
if self.options['share'] == '':
if self.options['shared'] == '':
parts.append(self.options['default-location'])
self.fix_shebang(self.options['default-location'])
......
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