Source code for spack.hooks.licensing

# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import os

import llnl.util.tty as tty
from llnl.util.filesystem import mkdirp
from llnl.util.symlink import symlink

import spack.util.editor as ed


[docs] def pre_install(spec): """This hook handles global license setup for licensed software.""" pkg = spec.package if pkg.license_required and not pkg.spec.external: set_up_license(pkg)
[docs] def set_up_license(pkg): """Prompt the user, letting them know that a license is required. For packages that rely on license files, a global license file is created and opened for editing. For packages that rely on environment variables to point to a license, a warning message is printed. For all other packages, documentation on how to set up a license is printed.""" # If the license can be stored in a file, create one if pkg.license_files: license_path = pkg.global_license_file if not os.path.exists(license_path): # Create a new license file write_license_file(pkg, license_path) # use spack.util.executable so the editor does not hang on return here ed.editor(license_path, exec_fn=ed.executable) else: # Use already existing license file tty.msg("Found already existing license %s" % license_path) # If not a file, what about an environment variable? elif pkg.license_vars: tty.warn( "A license is required to use %s. Please set %s to the " "full pathname to the license file, or port@host if you" " store your license keys on a dedicated license server" % (pkg.name, " or ".join(pkg.license_vars)) ) # If not a file or variable, suggest a website for further info elif pkg.license_url: tty.warn( "A license is required to use %s. See %s for details" % (pkg.name, pkg.license_url) ) # If all else fails, you're on your own else: tty.warn("A license is required to use %s" % pkg.name)
[docs] def write_license_file(pkg, license_path): """Writes empty license file. Comments give suggestions on alternative methods of installing a license.""" # License files linktargets = "" for f in pkg.license_files: linktargets += "\t%s\n" % f # Environment variables envvars = "" if pkg.license_vars: for varname in pkg.license_vars: envvars += "\t%s\n" % varname # Documentation url = "" if pkg.license_url: url += "\t%s\n" % pkg.license_url # Assemble. NB: pkg.license_comment will be prepended upon output. txt = """ A license is required to use package '{0}'. * If your system is already properly configured for such a license, save this file UNCHANGED. The system may be configured if: - A license file is installed in a default location. """.format( pkg.name ) if envvars: txt += """\ - One of the following environment variable(s) is set for you, possibly via a module file: {0} """.format( envvars ) txt += """\ * Otherwise, depending on the license you have, enter AT THE BEGINNING of this file: - the contents of your license file, or - the address(es) of your license server. After installation, the following symlink(s) will be added to point to this Spack-global file (relative to the installation prefix). {0} """.format( linktargets ) if url: txt += """\ * For further information on licensing, see: {0} """.format( url ) txt += """\ Recap: - You may not need to modify this file at all. - Otherwise, enter your license or server address AT THE BEGINNING. """ # Global license directory may not already exist if not os.path.exists(os.path.dirname(license_path)): os.makedirs(os.path.dirname(license_path)) # Output with open(license_path, "w") as f: for line in txt.splitlines(): f.write("{0}{1}\n".format(pkg.license_comment, line)) f.close()
[docs] def post_install(spec, explicit=None): """This hook symlinks local licenses to the global license for licensed software. """ pkg = spec.package if pkg.license_required and not pkg.spec.external: symlink_license(pkg)