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:
		 George Hartzell
					George Hartzell
				
			
				
					committed by
					
						 scheibelp
						scheibelp
					
				
			
			
				
	
			
			
			 scheibelp
						scheibelp
					
				
			
						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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user