summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Becker <becker33@llnl.gov>2015-09-03 09:21:19 -0700
committerGregory Becker <becker33@llnl.gov>2015-09-03 09:21:19 -0700
commit9c8e46dc228e096a83a892e5f53424bb3446d8f6 (patch)
tree49f29fc8dc3967810952384360606e95d4cd3d7d
parentc3246ee8ba26909ba73c3587ead9e61342692957 (diff)
downloadspack-9c8e46dc228e096a83a892e5f53424bb3446d8f6.tar.gz
spack-9c8e46dc228e096a83a892e5f53424bb3446d8f6.tar.bz2
spack-9c8e46dc228e096a83a892e5f53424bb3446d8f6.tar.xz
spack-9c8e46dc228e096a83a892e5f53424bb3446d8f6.zip
Added conservative locking to the spack commands that access the database at _index
-rw-r--r--lib/spack/spack/cmd/__init__.py22
-rw-r--r--lib/spack/spack/cmd/deactivate.py12
-rw-r--r--lib/spack/spack/cmd/diy.py60
-rw-r--r--lib/spack/spack/cmd/extensions.py4
-rw-r--r--lib/spack/spack/cmd/find.py7
-rw-r--r--lib/spack/spack/cmd/install.py22
-rw-r--r--lib/spack/spack/cmd/uninstall.py52
-rw-r--r--lib/spack/spack/database.py11
8 files changed, 104 insertions, 86 deletions
diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py
index fd3ef3ed27..c62d22979a 100644
--- a/lib/spack/spack/cmd/__init__.py
+++ b/lib/spack/spack/cmd/__init__.py
@@ -28,6 +28,7 @@ import sys
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)
-
- 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)
+ 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)
return matching_specs[0]
diff --git a/lib/spack/spack/cmd/deactivate.py b/lib/spack/spack/cmd/deactivate.py
index 1f0e303cdf..015809345a 100644
--- a/lib/spack/spack/cmd/deactivate.py
+++ b/lib/spack/spack/cmd/deactivate.py
@@ -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:
diff --git a/lib/spack/spack/cmd/diy.py b/lib/spack/spack/cmd/diy.py
index 6e7f10fba6..7403b9e3e8 100644
--- a/lib/spack/spack/cmd/diy.py
+++ b/lib/spack/spack/cmd/diy.py
@@ -27,6 +27,7 @@ import os
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.")
- sys.exit(1)
- else:
- tty.msg("Running 'spack edit -f %s'" % spec.name)
- edit_package(spec.name, True)
- return
+ 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.")
+ if not spec.version.concrete:
+ tty.die("spack diy spec must have a single, concrete version.")
- spec.concretize()
- package = spack.db.get(spec)
+ 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)
+ 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.
diff --git a/lib/spack/spack/cmd/extensions.py b/lib/spack/spack/cmd/extensions.py
index e919b1c4fb..66211e29a9 100644
--- a/lib/spack/spack/cmd/extensions.py
+++ b/lib/spack/spack/cmd/extensions.py
@@ -27,6 +27,7 @@ from external import argparse
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.")
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 6f9072e311..f7fa409ebb 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -32,6 +32,7 @@ import llnl.util.tty as tty
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:
diff --git a/lib/spack/spack/cmd/install.py b/lib/spack/spack/cmd/install.py
index acb688a092..330774b8d9 100644
--- a/lib/spack/spack/cmd/install.py
+++ b/lib/spack/spack/cmd/install.py
@@ -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)
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index 4870712eb6..4b0267dac2 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -27,6 +27,7 @@ from external import argparse
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
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index 6a429b68a9..9b759827d3 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -158,12 +158,12 @@ class Database(object):
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 @@ class Database(object):
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 @@ class Database(object):
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 @@ class Database(object):
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()