Added conservative locking to the spack commands that access the database at _index
This commit is contained in:
parent
c3246ee8ba
commit
9c8e46dc22
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.lang import attr_setdefault
|
from llnl.util.lang import attr_setdefault
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.spec
|
import spack.spec
|
||||||
@ -124,15 +125,16 @@ def elide_list(line_list, max_num=10):
|
|||||||
|
|
||||||
|
|
||||||
def disambiguate_spec(spec):
|
def disambiguate_spec(spec):
|
||||||
matching_specs = spack.installed_db.get_installed(spec)
|
with Read_Lock_Instance(spack.installed_db.lock,1800):
|
||||||
if not matching_specs:
|
matching_specs = spack.installed_db.get_installed(spec)
|
||||||
tty.die("Spec '%s' matches no installed packages." % spec)
|
if not matching_specs:
|
||||||
|
tty.die("Spec '%s' matches no installed packages." % spec)
|
||||||
|
|
||||||
elif len(matching_specs) > 1:
|
elif len(matching_specs) > 1:
|
||||||
args = ["%s matches multiple packages." % spec,
|
args = ["%s matches multiple packages." % spec,
|
||||||
"Matching packages:"]
|
"Matching packages:"]
|
||||||
args += [" " + str(s) for s in matching_specs]
|
args += [" " + str(s) for s in matching_specs]
|
||||||
args += ["Use a more specific spec."]
|
args += ["Use a more specific spec."]
|
||||||
tty.die(*args)
|
tty.die(*args)
|
||||||
|
|
||||||
return matching_specs[0]
|
return matching_specs[0]
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
from external import argparse
|
from external import argparse
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
@ -54,12 +55,13 @@ def deactivate(parser, args):
|
|||||||
if args.all:
|
if args.all:
|
||||||
if pkg.extendable:
|
if pkg.extendable:
|
||||||
tty.msg("Deactivating all extensions of %s" % pkg.spec.short_spec)
|
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:
|
for ext_pkg in ext_pkgs:
|
||||||
ext_pkg.spec.normalize()
|
ext_pkg.spec.normalize()
|
||||||
if ext_pkg.activated:
|
if ext_pkg.activated:
|
||||||
ext_pkg.do_deactivate(force=True)
|
ext_pkg.do_deactivate(force=True)
|
||||||
|
|
||||||
elif pkg.is_extension:
|
elif pkg.is_extension:
|
||||||
if not args.force and not spec.package.activated:
|
if not args.force and not spec.package.activated:
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
from external import argparse
|
from external import argparse
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
@ -54,40 +55,41 @@ def diy(self, args):
|
|||||||
if not args.spec:
|
if not args.spec:
|
||||||
tty.die("spack diy requires a package spec argument.")
|
tty.die("spack diy requires a package spec argument.")
|
||||||
|
|
||||||
specs = spack.cmd.parse_specs(args.spec)
|
with Write_Lock_Instance(spack.installed_db.lock,1800):
|
||||||
if len(specs) > 1:
|
specs = spack.cmd.parse_specs(args.spec)
|
||||||
tty.die("spack diy only takes one spec.")
|
if len(specs) > 1:
|
||||||
|
tty.die("spack diy only takes one spec.")
|
||||||
|
|
||||||
spec = specs[0]
|
spec = specs[0]
|
||||||
if not spack.db.exists(spec.name):
|
if not spack.db.exists(spec.name):
|
||||||
tty.warn("No such package: %s" % spec.name)
|
tty.warn("No such package: %s" % spec.name)
|
||||||
create = tty.get_yes_or_no("Create this package?", default=False)
|
create = tty.get_yes_or_no("Create this package?", default=False)
|
||||||
if not create:
|
if not create:
|
||||||
tty.msg("Exiting without creating.")
|
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)
|
sys.exit(1)
|
||||||
else:
|
|
||||||
tty.msg("Running 'spack edit -f %s'" % spec.name)
|
|
||||||
edit_package(spec.name, True)
|
|
||||||
return
|
|
||||||
|
|
||||||
if not spec.version.concrete:
|
# Forces the build to run out of the current directory.
|
||||||
tty.die("spack diy spec must have a single, concrete version.")
|
package.stage = DIYStage(os.getcwd())
|
||||||
|
|
||||||
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())
|
|
||||||
|
|
||||||
# TODO: make this an argument, not a global.
|
# TODO: make this an argument, not a global.
|
||||||
spack.do_checksum = False
|
spack.do_checksum = False
|
||||||
|
|
||||||
package.do_install(
|
package.do_install(
|
||||||
keep_prefix=args.keep_prefix,
|
keep_prefix=args.keep_prefix,
|
||||||
ignore_deps=args.ignore_deps,
|
ignore_deps=args.ignore_deps,
|
||||||
keep_stage=True) # don't remove source dir for DIY.
|
keep_stage=True) # don't remove source dir for DIY.
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
@ -80,7 +81,8 @@ def extensions(parser, args):
|
|||||||
colify(ext.name for ext in extensions)
|
colify(ext.name for ext in extensions)
|
||||||
|
|
||||||
# List specs of installed 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
|
print
|
||||||
if not installed:
|
if not installed:
|
||||||
tty.msg("None installed.")
|
tty.msg("None installed.")
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
from llnl.util.tty.colify import *
|
from llnl.util.tty.colify import *
|
||||||
from llnl.util.tty.color import *
|
from llnl.util.tty.color import *
|
||||||
from llnl.util.lang import *
|
from llnl.util.lang import *
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.spec
|
import spack.spec
|
||||||
@ -138,9 +139,11 @@ def find(parser, args):
|
|||||||
|
|
||||||
# Get all the specs the user asked for
|
# Get all the specs the user asked for
|
||||||
if not query_specs:
|
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:
|
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)
|
specs = set.union(*results)
|
||||||
|
|
||||||
if not args.mode:
|
if not args.mode:
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
from external import argparse
|
from external import argparse
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
@ -68,13 +69,14 @@ def install(parser, args):
|
|||||||
if args.no_checksum:
|
if args.no_checksum:
|
||||||
spack.do_checksum = False # TODO: remove this global.
|
spack.do_checksum = False # TODO: remove this global.
|
||||||
|
|
||||||
specs = spack.cmd.parse_specs(args.packages, concretize=True)
|
with Write_Lock_Instance(spack.installed_db.lock,1800):
|
||||||
for spec in specs:
|
specs = spack.cmd.parse_specs(args.packages, concretize=True)
|
||||||
package = spack.db.get(spec)
|
for spec in specs:
|
||||||
package.do_install(
|
package = spack.db.get(spec)
|
||||||
keep_prefix=args.keep_prefix,
|
package.do_install(
|
||||||
keep_stage=args.keep_stage,
|
keep_prefix=args.keep_prefix,
|
||||||
ignore_deps=args.ignore_deps,
|
keep_stage=args.keep_stage,
|
||||||
make_jobs=args.jobs,
|
ignore_deps=args.ignore_deps,
|
||||||
verbose=args.verbose,
|
make_jobs=args.jobs,
|
||||||
fake=args.fake)
|
verbose=args.verbose,
|
||||||
|
fake=args.fake)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
from llnl.util.lock import *
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
@ -53,35 +54,36 @@ def uninstall(parser, args):
|
|||||||
if not args.packages:
|
if not args.packages:
|
||||||
tty.die("uninstall requires at least one package argument.")
|
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.
|
# For each spec provided, make sure it refers to only one package.
|
||||||
# Fail and ask user to be unambiguous if it doesn't
|
# Fail and ask user to be unambiguous if it doesn't
|
||||||
pkgs = []
|
pkgs = []
|
||||||
for spec in specs:
|
for spec in specs:
|
||||||
matching_specs = spack.installed_db.get_installed(spec)
|
matching_specs = spack.installed_db.get_installed(spec)
|
||||||
if not args.all and len(matching_specs) > 1:
|
if not args.all and len(matching_specs) > 1:
|
||||||
tty.error("%s matches multiple packages:" % spec)
|
tty.error("%s matches multiple packages:" % spec)
|
||||||
print
|
print
|
||||||
display_specs(matching_specs, long=True)
|
display_specs(matching_specs, long=True)
|
||||||
print
|
print
|
||||||
print "You can either:"
|
print "You can either:"
|
||||||
print " a) Use a more specific spec, or"
|
print " a) Use a more specific spec, or"
|
||||||
print " b) use spack uninstall -a to uninstall ALL matching specs."
|
print " b) use spack uninstall -a to uninstall ALL matching specs."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(matching_specs) == 0:
|
if len(matching_specs) == 0:
|
||||||
if args.force: continue
|
if args.force: continue
|
||||||
tty.die("%s does not match any installed packages." % spec)
|
tty.die("%s does not match any installed packages." % spec)
|
||||||
|
|
||||||
for s in matching_specs:
|
for s in matching_specs:
|
||||||
try:
|
try:
|
||||||
# should work if package is known to spack
|
# should work if package is known to spack
|
||||||
pkgs.append(s.package)
|
pkgs.append(s.package)
|
||||||
|
|
||||||
except spack.packages.UnknownPackageError, e:
|
except spack.packages.UnknownPackageError, e:
|
||||||
# The package.py file has gone away -- but still want to uninstall.
|
# The package.py file has gone away -- but still want to uninstall.
|
||||||
spack.Package(s).do_uninstall(force=True)
|
spack.Package(s).do_uninstall(force=True)
|
||||||
|
|
||||||
# Sort packages to be uninstalled by the number of installed dependents
|
# Sort packages to be uninstalled by the number of installed dependents
|
||||||
# This ensures we do things in the right order
|
# This ensures we do things in the right order
|
||||||
|
@ -158,12 +158,12 @@ def write(self):
|
|||||||
within the same lock, so there is no need to refresh
|
within the same lock, so there is no need to refresh
|
||||||
the database within write()
|
the database within write()
|
||||||
"""
|
"""
|
||||||
temp_name = os.getpid() + socket.getfqdn() + ".temp"
|
temp_name = str(os.getpid()) + socket.getfqdn() + ".temp"
|
||||||
temp_file = path.join(self._root,temp_name)
|
temp_file = join_path(self._root,temp_name)
|
||||||
with open(self.temp_path,'w') as f:
|
with open(temp_file,'w') as f:
|
||||||
self._last_write_time = int(time.time())
|
self._last_write_time = int(time.time())
|
||||||
self._write_database_to_yaml(f)
|
self._write_database_to_yaml(f)
|
||||||
os.rename(temp_name,self._file_path)
|
os.rename(temp_file,self._file_path)
|
||||||
|
|
||||||
def is_dirty(self):
|
def is_dirty(self):
|
||||||
"""
|
"""
|
||||||
@ -184,6 +184,7 @@ def add(self, spec, path):
|
|||||||
sph['path']=path
|
sph['path']=path
|
||||||
sph['hash']=spec.dag_hash()
|
sph['hash']=spec.dag_hash()
|
||||||
|
|
||||||
|
#Should always already be locked
|
||||||
with Write_Lock_Instance(self.lock,60):
|
with Write_Lock_Instance(self.lock,60):
|
||||||
self.read_database()
|
self.read_database()
|
||||||
self._data.append(sph)
|
self._data.append(sph)
|
||||||
@ -197,6 +198,7 @@ def remove(self, spec):
|
|||||||
Searches for and removes the specified spec
|
Searches for and removes the specified spec
|
||||||
Writes the database back to memory
|
Writes the database back to memory
|
||||||
"""
|
"""
|
||||||
|
#Should always already be locked
|
||||||
with Write_Lock_Instance(self.lock,60):
|
with Write_Lock_Instance(self.lock,60):
|
||||||
self.read_database()
|
self.read_database()
|
||||||
|
|
||||||
@ -237,6 +239,7 @@ def installed_package_specs(self):
|
|||||||
Read installed package names from the database
|
Read installed package names from the database
|
||||||
and return their specs
|
and return their specs
|
||||||
"""
|
"""
|
||||||
|
#Should always already be locked
|
||||||
with Read_Lock_Instance(self.lock,60):
|
with Read_Lock_Instance(self.lock,60):
|
||||||
self.read_database()
|
self.read_database()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user