#!/usr/bin/env python3 """ Program to install locally the LCG binary tarfile. It downsloads, expands and relocates the binary tarfile. Version 1.0 """ #------------------------------------------------------------------------------- from __future__ import print_function import os, sys, tarfile, subprocess, shutil try: import argparse except ImportError: import argparse2 as argparse if sys.version_info[0] >= 3 : import urllib.request as urllib2 else: import urllib2 #---install_tarfile------------------------------------------------------------- def install_tarfile(urltarfile, prefix, lcgprefix, with_hash=True, with_link=True): #---Installing with hash implies to install at the prefix parent directory # and make a symlink to it at prefix---------------------------------------- orig_prefix = prefix if with_hash and with_link : prefix = os.path.dirname(prefix) #---Download and expand tarfile----------------------------------------------- try : filename = os.path.basename(urltarfile) items = os.path.splitext(filename)[0].split('-') hash = items[-5].split('_')[-1] platform = '-'.join(items[-4:]) except: print("Binary tarfile name '%s' ill-formed" % filename) sys.exit(1) print('==== Downloading and installing %s' % urltarfile) counter = 0 success = False while counter < 5 and not success: counter += 1 try: resp = urllib2.urlopen(urltarfile) tar = tarfile.open(fileobj=resp, mode='r|gz', errorlevel=1) dirname, version = os.path.split(tar.next().name) tar.extractall(path=prefix) success = True except urllib2.HTTPError as detail: print('Error downloading %s : %s' % (urltarfile, detail)) except tarfile.ReadError as detail: print('Error untaring %s : %s' %(urltarfile, detail)) except: print('Unexpected error:', sys.exc_info()[0]) if not success: sys.exit(1) #---rename the version directory---------------------------------------------- if with_hash : old_dirname = os.path.join(prefix, dirname, version) new_dirname = os.path.join(prefix, dirname, version + '-' + hash) if not os.path.exists(new_dirname): os.mkdir(new_dirname) if os.path.exists(os.path.join(new_dirname, platform)): shutil.rmtree(os.path.join(new_dirname, platform)) os.rename(os.path.join(old_dirname, platform), os.path.join(new_dirname, platform)) shutil.rmtree(old_dirname) full_version = version + '-' + hash else : full_version = version install_path = os.path.join(prefix, dirname, full_version, platform) #---run the post-install------------------------------------------------------ postinstall = os.path.join(install_path, '.post-install.sh') if os.path.exists(postinstall) : #---Replace the old post-install script with new one with open(postinstall) as f: script = f.read() if '#!/bin/sh' in script or 'RPM_INSTALL_PREFIX' not in script: f.close() shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)),'post-install.sh'), postinstall) os.environ['INSTALLDIR'] = prefix if lcgprefix : os.environ['LCGRELEASES'] = lcgprefix.replace(';',':').replace(' ',':') if not with_hash : os.environ['NIGHTLY_MODE'] = '1' with open(os.devnull, 'w') as devnull: rc = subprocess.call([postinstall], stdout=devnull) if rc != 0: raise RuntimeError("Post-install for package {0} failed!".format(filename)) #---run the fix-mac-relocation------------------------------------------------ if sys.platform == 'darwin': from fix_mac_relocation import fix_darwin_install_name fix_darwin_install_name(install_path, orig_prefix) #---create a link to the hashed install--------------------------------------- if with_hash and with_link : dest = os.path.join(orig_prefix, dirname, version) if not os.path.exists(dest) : os.makedirs(dest) os.symlink(os.path.relpath(install_path, dest), os.path.join(dest, platform)) #---Main program---------------------------------------------------------------- if __name__ == '__main__': #---Parse the arguments------------------------------------------------------- parser = argparse.ArgumentParser() parser.add_argument('--url', dest='url', help='URL of the binary tarfile', required=True) parser.add_argument('--prefix', dest='prefix', help='prefix to the installation', required=True) parser.add_argument('--lcgprefix', dest='lcgprefix', help='LCG prefix to the installation', default='', required=False) parser.add_argument('--nohash', dest='with_hash', action='store_false', help='Install without hash', default=not 'RELEASE_MODE' in os.environ and not 'NIGHTLY_MODE' in os.environ) args = parser.parse_args() install_tarfile(args.url, args.prefix, args.lcgprefix, args.with_hash)