Added conservative locking to the spack commands that access the database at _index

This commit is contained in:
Gregory Becker 2015-09-03 09:21:19 -07:00
parent c3246ee8ba
commit 9c8e46dc22
8 changed files with 105 additions and 87 deletions

View File

@ -28,6 +28,7 @@
import llnl.util.tty as tty
from llnl.util.lang import attr_setdefault
from llnl.util.lock import *
import spack
import spack.spec
@ -124,15 +125,16 @@ def elide_list(line_list, max_num=10):
def disambiguate_spec(spec):
matching_specs = spack.installed_db.get_installed(spec)
if not matching_specs:
tty.die("Spec '%s' matches no installed packages." % spec)
with Read_Lock_Instance(spack.installed_db.lock,1800):
matching_specs = spack.installed_db.get_installed(spec)
if not matching_specs:
tty.die("Spec '%s' matches no installed packages." % spec)
elif len(matching_specs) > 1:
args = ["%s matches multiple packages." % spec,
"Matching packages:"]
args += [" " + str(s) for s in matching_specs]
args += ["Use a more specific spec."]
tty.die(*args)
elif len(matching_specs) > 1:
args = ["%s matches multiple packages." % spec,
"Matching packages:"]
args += [" " + str(s) for s in matching_specs]
args += ["Use a more specific spec."]
tty.die(*args)
return matching_specs[0]

View File

@ -24,6 +24,7 @@
##############################################################################
from external import argparse
import llnl.util.tty as tty
from llnl.util.lock import *
import spack
import spack.cmd
@ -54,12 +55,13 @@ def deactivate(parser, args):
if args.all:
if pkg.extendable:
tty.msg("Deactivating all extensions of %s" % pkg.spec.short_spec)
ext_pkgs = spack.installed_db.installed_extensions_for(spec)
with Read_Lock_Instance(spack.installed_db.lock,1800):
ext_pkgs = spack.installed_db.installed_extensions_for(spec)
for ext_pkg in ext_pkgs:
ext_pkg.spec.normalize()
if ext_pkg.activated:
ext_pkg.do_deactivate(force=True)
for ext_pkg in ext_pkgs:
ext_pkg.spec.normalize()
if ext_pkg.activated:
ext_pkg.do_deactivate(force=True)
elif pkg.is_extension:
if not args.force and not spec.package.activated:

View File

@ -27,6 +27,7 @@
from external import argparse
import llnl.util.tty as tty
from llnl.util.lock import *
import spack
import spack.cmd
@ -54,40 +55,41 @@ def diy(self, args):
if not args.spec:
tty.die("spack diy requires a package spec argument.")
specs = spack.cmd.parse_specs(args.spec)
if len(specs) > 1:
tty.die("spack diy only takes one spec.")
with Write_Lock_Instance(spack.installed_db.lock,1800):
specs = spack.cmd.parse_specs(args.spec)
if len(specs) > 1:
tty.die("spack diy only takes one spec.")
spec = specs[0]
if not spack.db.exists(spec.name):
tty.warn("No such package: %s" % spec.name)
create = tty.get_yes_or_no("Create this package?", default=False)
if not create:
tty.msg("Exiting without creating.")
spec = specs[0]
if not spack.db.exists(spec.name):
tty.warn("No such package: %s" % spec.name)
create = tty.get_yes_or_no("Create this package?", default=False)
if not create:
tty.msg("Exiting without creating.")
sys.exit(1)
else:
tty.msg("Running 'spack edit -f %s'" % spec.name)
edit_package(spec.name, True)
return
if not spec.version.concrete:
tty.die("spack diy spec must have a single, concrete version.")
spec.concretize()
package = spack.db.get(spec)
if package.installed:
tty.error("Already installed in %s" % package.prefix)
tty.msg("Uninstall or try adding a version suffix for this DIY build.")
sys.exit(1)
else:
tty.msg("Running 'spack edit -f %s'" % spec.name)
edit_package(spec.name, True)
return
if not spec.version.concrete:
tty.die("spack diy spec must have a single, concrete version.")
spec.concretize()
package = spack.db.get(spec)
if package.installed:
tty.error("Already installed in %s" % package.prefix)
tty.msg("Uninstall or try adding a version suffix for this DIY build.")
sys.exit(1)
# Forces the build to run out of the current directory.
package.stage = DIYStage(os.getcwd())
# Forces the build to run out of the current directory.
package.stage = DIYStage(os.getcwd())
# TODO: make this an argument, not a global.
spack.do_checksum = False
spack.do_checksum = False
package.do_install(
keep_prefix=args.keep_prefix,
ignore_deps=args.ignore_deps,
keep_stage=True) # don't remove source dir for DIY.
package.do_install(
keep_prefix=args.keep_prefix,
ignore_deps=args.ignore_deps,
keep_stage=True) # don't remove source dir for DIY.

View File

@ -27,6 +27,7 @@
import llnl.util.tty as tty
from llnl.util.tty.colify import colify
from llnl.util.lock import *
import spack
import spack.cmd
@ -80,7 +81,8 @@ def extensions(parser, args):
colify(ext.name for ext in extensions)
# List specs of installed extensions.
installed = [s.spec for s in spack.installed_db.installed_extensions_for(spec)]
with Read_Lock_Instance(spack.installed_db.lock,1800):
installed = [s.spec for s in spack.installed_db.installed_extensions_for(spec)]
print
if not installed:
tty.msg("None installed.")

View File

@ -32,6 +32,7 @@
from llnl.util.tty.colify import *
from llnl.util.tty.color import *
from llnl.util.lang import *
from llnl.util.lock import *
import spack
import spack.spec
@ -138,9 +139,11 @@ def find(parser, args):
# Get all the specs the user asked for
if not query_specs:
specs = set(spack.installed_db.installed_package_specs())
with Read_Lock_Instance(spack.installed_db.lock,1800):
specs = set(spack.installed_db.installed_package_specs())
else:
results = [set(spack.installed_db.get_installed(qs)) for qs in query_specs]
with Read_Lock_Instance(spack.installed_db.lock,1800):
results = [set(spack.installed_db.get_installed(qs)) for qs in query_specs]
specs = set.union(*results)
if not args.mode:

View File

@ -25,6 +25,7 @@
from external import argparse
import llnl.util.tty as tty
from llnl.util.lock import *
import spack
import spack.cmd
@ -68,13 +69,14 @@ def install(parser, args):
if args.no_checksum:
spack.do_checksum = False # TODO: remove this global.
specs = spack.cmd.parse_specs(args.packages, concretize=True)
for spec in specs:
package = spack.db.get(spec)
package.do_install(
keep_prefix=args.keep_prefix,
keep_stage=args.keep_stage,
ignore_deps=args.ignore_deps,
make_jobs=args.jobs,
verbose=args.verbose,
fake=args.fake)
with Write_Lock_Instance(spack.installed_db.lock,1800):
specs = spack.cmd.parse_specs(args.packages, concretize=True)
for spec in specs:
package = spack.db.get(spec)
package.do_install(
keep_prefix=args.keep_prefix,
keep_stage=args.keep_stage,
ignore_deps=args.ignore_deps,
make_jobs=args.jobs,
verbose=args.verbose,
fake=args.fake)

View File

@ -27,6 +27,7 @@
import llnl.util.tty as tty
from llnl.util.tty.colify import colify
from llnl.util.lock import *
import spack
import spack.cmd
@ -53,35 +54,36 @@ def uninstall(parser, args):
if not args.packages:
tty.die("uninstall requires at least one package argument.")
specs = spack.cmd.parse_specs(args.packages)
with Write_Lock_Instance(spack.installed_db.lock,1800):
specs = spack.cmd.parse_specs(args.packages)
# For each spec provided, make sure it refers to only one package.
# Fail and ask user to be unambiguous if it doesn't
pkgs = []
for spec in specs:
matching_specs = spack.installed_db.get_installed(spec)
if not args.all and len(matching_specs) > 1:
tty.error("%s matches multiple packages:" % spec)
print
display_specs(matching_specs, long=True)
print
print "You can either:"
print " a) Use a more specific spec, or"
print " b) use spack uninstall -a to uninstall ALL matching specs."
sys.exit(1)
# For each spec provided, make sure it refers to only one package.
# Fail and ask user to be unambiguous if it doesn't
pkgs = []
for spec in specs:
matching_specs = spack.installed_db.get_installed(spec)
if not args.all and len(matching_specs) > 1:
tty.error("%s matches multiple packages:" % spec)
print
display_specs(matching_specs, long=True)
print
print "You can either:"
print " a) Use a more specific spec, or"
print " b) use spack uninstall -a to uninstall ALL matching specs."
sys.exit(1)
if len(matching_specs) == 0:
if args.force: continue
tty.die("%s does not match any installed packages." % spec)
if len(matching_specs) == 0:
if args.force: continue
tty.die("%s does not match any installed packages." % spec)
for s in matching_specs:
try:
# should work if package is known to spack
pkgs.append(s.package)
for s in matching_specs:
try:
# should work if package is known to spack
pkgs.append(s.package)
except spack.packages.UnknownPackageError, e:
# The package.py file has gone away -- but still want to uninstall.
spack.Package(s).do_uninstall(force=True)
except spack.packages.UnknownPackageError, e:
# The package.py file has gone away -- but still want to uninstall.
spack.Package(s).do_uninstall(force=True)
# Sort packages to be uninstalled by the number of installed dependents
# This ensures we do things in the right order

View File

@ -158,12 +158,12 @@ def write(self):
within the same lock, so there is no need to refresh
the database within write()
"""
temp_name = os.getpid() + socket.getfqdn() + ".temp"
temp_file = path.join(self._root,temp_name)
with open(self.temp_path,'w') as f:
temp_name = str(os.getpid()) + socket.getfqdn() + ".temp"
temp_file = join_path(self._root,temp_name)
with open(temp_file,'w') as f:
self._last_write_time = int(time.time())
self._write_database_to_yaml(f)
os.rename(temp_name,self._file_path)
os.rename(temp_file,self._file_path)
def is_dirty(self):
"""
@ -184,6 +184,7 @@ def add(self, spec, path):
sph['path']=path
sph['hash']=spec.dag_hash()
#Should always already be locked
with Write_Lock_Instance(self.lock,60):
self.read_database()
self._data.append(sph)
@ -197,6 +198,7 @@ def remove(self, spec):
Searches for and removes the specified spec
Writes the database back to memory
"""
#Should always already be locked
with Write_Lock_Instance(self.lock,60):
self.read_database()
@ -237,6 +239,7 @@ def installed_package_specs(self):
Read installed package names from the database
and return their specs
"""
#Should always already be locked
with Read_Lock_Instance(self.lock,60):
self.read_database()