perl: add write permissions to update config files (#5746)
Perl installs a couple of config files that need to be munged so that they don't refer to the spack compiler. These files are installed read-only. Behind the scenes 'filter_file' moves its file to a safe place, and tries to create a working file that is both O_WRONLY and has the perms of the original file. On an NFSv4 filesystem, the combination of 'r--r--r--' and O_WRONLY throws a permissions error. This commit adds a simple context manager that temporarily makes the files writable.
This commit is contained in:
parent
464e558aea
commit
ad5fb40d75
@ -32,6 +32,7 @@
|
|||||||
#
|
#
|
||||||
from spack import *
|
from spack import *
|
||||||
import os
|
import os
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
|
class Perl(Package): # Perl doesn't use Autotools, it should subclass Package
|
||||||
@ -186,7 +187,9 @@ def setup_dependent_package(self, module, dependent_spec):
|
|||||||
def filter_config_dot_pm(self):
|
def filter_config_dot_pm(self):
|
||||||
"""Run after install so that Config.pm records the compiler that Spack
|
"""Run after install so that Config.pm records the compiler that Spack
|
||||||
built the package with. If this isn't done, $Config{cc} will
|
built the package with. If this isn't done, $Config{cc} will
|
||||||
be set to Spack's cc wrapper script.
|
be set to Spack's cc wrapper script. These files are read-only, which
|
||||||
|
frustrates filter_file on some filesystems (NFSv4), so make them
|
||||||
|
temporarily writable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
kwargs = {'ignore_absent': True, 'backup': False, 'string': False}
|
kwargs = {'ignore_absent': True, 'backup': False, 'string': False}
|
||||||
@ -196,6 +199,7 @@ def filter_config_dot_pm(self):
|
|||||||
config_dot_pm = perl('-MModule::Loaded', '-MConfig', '-e',
|
config_dot_pm = perl('-MModule::Loaded', '-MConfig', '-e',
|
||||||
'print is_loaded(Config)', output=str)
|
'print is_loaded(Config)', output=str)
|
||||||
|
|
||||||
|
with self.make_briefly_writable(config_dot_pm):
|
||||||
match = 'cc *=>.*'
|
match = 'cc *=>.*'
|
||||||
substitute = "cc => '{cc}',".format(cc=self.compiler.cc)
|
substitute = "cc => '{cc}',".format(cc=self.compiler.cc)
|
||||||
filter_file(match, substitute, config_dot_pm, **kwargs)
|
filter_file(match, substitute, config_dot_pm, **kwargs)
|
||||||
@ -204,6 +208,7 @@ def filter_config_dot_pm(self):
|
|||||||
d = os.path.dirname(config_dot_pm)
|
d = os.path.dirname(config_dot_pm)
|
||||||
config_heavy = join_path(d, 'Config_heavy.pl')
|
config_heavy = join_path(d, 'Config_heavy.pl')
|
||||||
|
|
||||||
|
with self.make_briefly_writable(config_heavy):
|
||||||
match = '^cc=.*'
|
match = '^cc=.*'
|
||||||
substitute = "cc='{cc}'".format(cc=self.compiler.cc)
|
substitute = "cc='{cc}'".format(cc=self.compiler.cc)
|
||||||
filter_file(match, substitute, config_heavy, **kwargs)
|
filter_file(match, substitute, config_heavy, **kwargs)
|
||||||
@ -211,3 +216,11 @@ def filter_config_dot_pm(self):
|
|||||||
match = '^ld=.*'
|
match = '^ld=.*'
|
||||||
substitute = "ld='{ld}'".format(ld=self.compiler.cc)
|
substitute = "ld='{ld}'".format(ld=self.compiler.cc)
|
||||||
filter_file(match, substitute, config_heavy, **kwargs)
|
filter_file(match, substitute, config_heavy, **kwargs)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def make_briefly_writable(self, path):
|
||||||
|
"""Temporarily make a file writable, then reset"""
|
||||||
|
perm = os.stat(path).st_mode
|
||||||
|
os.chmod(path, perm | 0o200)
|
||||||
|
yield
|
||||||
|
os.chmod(path, perm)
|
||||||
|
Loading…
Reference in New Issue
Block a user