install_binary_tarfile.py 4.74 KB
Newer Older
1
#!/usr/bin/env python3
2
3
4
5
6
7
8
9
"""
Program to install locally the LCG binary tarfile. It downsloads, expands and relocates the binary tarfile. 
<pere.mato@cern.ch>
Version 1.0
"""

#-------------------------------------------------------------------------------
from __future__ import print_function
10
11
12
13
14
15
import os, sys, tarfile, subprocess, shutil
try:
    import argparse
except ImportError:
    import argparse2 as argparse

16
17
18
19
20
21
if sys.version_info[0] >= 3 :
  import urllib.request as urllib2
else:
  import urllib2

#---install_tarfile-------------------------------------------------------------
22
def install_tarfile(urltarfile, prefix, lcgprefix, with_hash=True, with_link=True):
23
24
25
  #---Installing with hash implies to install at the prefix parent directory
  #   and make a symlink to it at prefix----------------------------------------
  orig_prefix = prefix
Pere Mato Vila's avatar
Pere Mato Vila committed
26
  if with_hash and with_link :
27
28
    prefix = os.path.dirname(prefix)
  #---Download and expand tarfile-----------------------------------------------  
29
30
31
32
33
34
35
36
37
38
  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)
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  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:
56
57
    sys.exit(1)

58
59
60
61
62
63
64
65
66
67
68
69
  #---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)
70

71
72
  #---run the post-install------------------------------------------------------
  postinstall = os.path.join(install_path, '.post-install.sh')
73
  if os.path.exists(postinstall) :
74
75
    #---Replace the old post-install script with new one
    with open(postinstall) as f:
76
77
      script = f.read()
      if '#!/bin/sh' in script or 'RPM_INSTALL_PREFIX' not in script:
78
79
        f.close()
        shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)),'post-install.sh'), postinstall)
80
    os.environ['INSTALLDIR'] = prefix
81
    if lcgprefix  :
82
      os.environ['LCGRELEASES'] = lcgprefix.replace(';',':').replace(' ',':')
83
84
    if not with_hash :
      os.environ['NIGHTLY_MODE'] = '1'
85
    with open(os.devnull, 'w') as devnull:
86
      rc = subprocess.call([postinstall], stdout=devnull)
87
88
      if rc != 0:
        raise RuntimeError("Post-install for package {0} failed!".format(filename))
89

90
91
92
93
94
95
  #---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---------------------------------------
96
  if with_hash and with_link :
97
98
    dest = os.path.join(orig_prefix, dirname, version)
    if not os.path.exists(dest) : os.makedirs(dest)
99
    os.symlink(os.path.relpath(install_path, dest), os.path.join(dest, platform))
100

101
102
#---Main program----------------------------------------------------------------
if __name__ == '__main__':
103

104
105
106
107
108
  #---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)
109
  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)
110
  args = parser.parse_args()
111
  install_tarfile(args.url, args.prefix, args.lcgprefix, args.with_hash)