Changeset 2fb99de in flex_extract.git for python/install.py


Ignore:
Timestamp:
Sep 20, 2018, 11:56:37 AM (6 years ago)
Author:
Anne Philipp <anne.philipp@…>
Branches:
master, ctbto, dev
Children:
5d42acd
Parents:
3232589
Message:

introduced config with path definitions and changed py files accordingly; Installation works; some tests were added for tarball making; Problems in submission to ecgate

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/install.py

    r222aa11 r2fb99de  
    1212#        - added documentation
    1313#        - moved install_args_and_control in here
     14#        - splitted code in smaller functions
     15#        - delete convert build files in here instead of compile job script
     16#        - changed static path names to Variables from config file
    1417#
    1518# @License:
     
    3437#    - install_via_gateway
    3538#    - mk_tarball
     39#    - un_tarball
    3640#    - mk_env_vars
    3741#    - mk_compilejob
     
    4751import os
    4852import sys
     53import glob
    4954import subprocess
    5055import inspect
     
    5257
    5358# software specific classes and modules from flex_extract
     59import _config
    5460from ControlFile import ControlFile
    5561from UioFiles import UioFiles
    5662from tools import make_dir, put_file_to_ecserver, submit_job_to_ecserver
    57 
    58 # add path to pythonpath so that python finds its buddies
    59 LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
    60     inspect.getfile(inspect.currentframe())))
    61 if LOCAL_PYTHON_PATH not in sys.path:
    62     sys.path.append(LOCAL_PYTHON_PATH)
    63 
    64 _VERSION_STR = '7.1'
    6563
    6664# ------------------------------------------------------------------------------
     
    8078    '''
    8179
    82     os.chdir(LOCAL_PYTHON_PATH)
     80    #os.chdir(_config.PATH_LOCAL_PYTHON)
     81
    8382    args = get_install_cmdline_arguments()
    8483
     
    8685        c = ControlFile(args.controlfile)
    8786    except IOError:
    88         print 'Could not read CONTROL file "' + args.controlfile + '"'
    89         print 'Either it does not exist or its syntax is wrong.'
    90         print 'Try "' + sys.argv[0].split('/')[-1] + \
    91               ' -h" to print usage information'
     87        print('Could not read CONTROL file "' + args.controlfile + '"')
     88        print('Either it does not exist or its syntax is wrong.')
     89        print('Try "' + sys.argv[0].split('/')[-1] +
     90              ' -h" to print usage information')
    9291        exit(1)
    9392
     
    134133                        servers (to find grib2flexpart and COMMAND file)\n\
    135134                        Normally flex_extract resides in the scripts directory \
    136                         of the FLEXPART distribution, thus the:")
     135                        of the FLEXPART distribution.")
    137136
    138137    # arguments for job submission to ECMWF, only needed by submit.py
     
    171170        <nothing>
    172171    '''
    173 
    174     ecd = c.ecmwfdatadir
    175     tarball_name = 'flex_extract_v' + _VERSION_STR + '.tar'
    176     target_dir = 'flex_extract_v' + _VERSION_STR
    177     fortran_executable = 'CONVERT2'
     172    import tarfile
     173
     174    ecd = _config.PATH_FLEXEXTRACT_DIR
     175    tarball_name = _config.FLEXEXTRACT_DIRNAME + '.tar'
     176    tar_file = os.path.join(ecd, tarball_name)
     177
     178    target_dirname = _config.FLEXEXTRACT_DIRNAME
     179    fortran_executable = _config.FORTRAN_EXECUTABLE
    178180
    179181    if c.install_target.lower() != 'local': # ecgate or cca
    180182
    181         mk_compilejob(ecd + 'python/compilejob.temp', c.makefile,
    182                       c.install_target, c.ecuid, c.ecgid,
     183        mk_compilejob(c.makefile, c.install_target, c.ecuid, c.ecgid,
    183184                      c.flexpart_root_scripts)
    184185
    185         mk_job_template(ecd + 'python/job.temp.o', c.ecuid, c.ecgid, c.gateway,
     186        mk_job_template(c.ecuid, c.ecgid, c.gateway,
    186187                        c.destination, c.flexpart_root_scripts)
    187188
    188         mk_env_vars(ecd, c.ecuid, c.ecgid, c.gateway, c.destination)
    189 
    190         #os.chdir('/')
    191 
    192         mk_tarball(ecd, tarball_name)
     189        mk_env_vars(c.ecuid, c.ecgid, c.gateway, c.destination)
     190
     191        mk_tarball(tar_file)
    193192
    194193        put_file_to_ecserver(ecd, tarball_name, c.install_target,
    195194                             c.ecuid, c.ecgid)
    196195
    197         submit_job_to_ecserver(ecd + '/python/', c.install_target,
    198                                'compilejob.ksh')
    199 
    200         print 'job compilation script has been submitted to ecgate for ' + \
    201               'installation in ' + c.flexpart_root_scripts + \
    202                '/' + target_dir
    203         print 'You should get an email with subject "flexcompile" within ' + \
    204               'the next few minutes!'
     196        submit_job_to_ecserver(c.install_target,
     197                               os.path.join(_config.PATH_RELATIVE_JOBSCRIPTS,
     198                                            _config.FILE_INSTALL_COMPILEJOB))
     199
     200        print('job compilation script has been submitted to ecgate for ' +
     201              'installation in ' + c.flexpart_root_scripts +
     202               '/' + target_dirname)
     203        print('You should get an email with subject "flexcompile" within ' +
     204              'the next few minutes!')
    205205
    206206    else: #local
    207         if not c.flexpart_root_scripts or c.flexpart_root_scripts == '../':
    208             print 'WARNING: FLEXPART_ROOT_SCRIPTS has not been specified'
    209             print 'There will be only the compilation of ' + \
    210                   ' in ' + ecd + '/src'
    211             os.chdir(ecd + '/src')
     207        if c.flexpart_root_scripts == _config.PATH_FLEXEXTRACT_DIR :
     208            print('WARNING: FLEXPART_ROOT_SCRIPTS has not been specified')
     209            print('flex_extract will be installed in here by compiling the ' +
     210                  'Fortran source in ' + _config.PATH_FORTRAN_SRC)
     211            os.chdir(_config.PATH_FORTRAN_SRC)
    212212        else: # creates the target working directory for flex_extract
    213213            c.flexpart_root_scripts = os.path.expandvars(os.path.expanduser(
    214                 c.flexpart_root_scripts))
     214                                        c.flexpart_root_scripts))
    215215            if os.path.abspath(ecd) != os.path.abspath(c.flexpart_root_scripts):
    216                 os.chdir('/')
    217                 mk_tarball(ecd, tarball_name)
    218                 make_dir(c.flexpart_root_scripts + '/' + target_dir)
    219                 os.chdir(c.flexpart_root_scripts + '/' + target_dir)
    220                 print 'Untar ...'
    221                 subprocess.check_call(['tar', '-xvf',
    222                                        ecd + '../' + tarball_name])
    223                 os.chdir(c.flexpart_root_scripts + '/' + target_dir + '/src')
     216                mk_tarball(tar_file)
     217                make_dir(os.path.join(c.flexpart_root_scripts,
     218                                      target_dirname))
     219                os.chdir(os.path.join(c.flexpart_root_scripts,
     220                                      target_dirname))
     221                un_tarball(tar_file)
     222                os.chdir(os.path.join(c.flexpart_root_scripts,
     223                                      target_dirname,
     224                                      _config.PATH_RELATIVE_FORTRAN_SRC))
    224225
    225226        # Create Fortran executable - CONVERT2
    226         print 'Install ' + target_dir + ' software on ' + \
    227               c.install_target + ' in directory ' + \
    228               os.path.abspath(os.getcwd() + '/../') + '\n'
    229 
    230         delete_convert_build('')
    231         make_convert_build('', c.makefile, fortran_executable)
    232 
    233     return
    234 
    235 def mk_tarball(ecd, tarname):
    236     '''
    237     @Description:
    238         Creates a tarball from all files which need to be sent to the
     227        print('Install ' + target_dirname + ' software at ' +
     228              c.install_target + ' in directory ' +
     229              os.path.abspath(c.flexpart_root_scripts) + '\n')
     230
     231        delete_convert_build('.')
     232        make_convert_build('.', c.makefile)
     233
     234        os.chdir(ecd)
     235        if os.path.isfile(tar_file):
     236            os.remove(tar_file)
     237
     238    return
     239
     240def mk_tarball(tarball_path):
     241    '''
     242    @Description:
     243        Creates a tarball with all necessary files which need to be sent to the
    239244        installation directory.
    240245        It does not matter if this is local or remote.
    241246        Collects all python files, the Fortran source and makefiles,
    242         the ECMWF_ENV file, the CONTROL files as well as
    243         the korn shell and template files.
    244 
    245     @Input:
    246         ecd: string
    247             The path were the file is to be stored.
    248 
    249         tarname: string
    250             The name of the file to send to the ECMWF server.
    251 
    252     @Return:
    253         <nothing>
    254     '''
    255 
    256     print 'Create tarball ...'
     247        the ECMWF_ENV file, the CONTROL files as well as the
     248        template files.
     249
     250    @Input:
     251        tarball_path: string
     252            The complete path to the tar file which will contain all
     253            relevant data for flex_extract.
     254
     255    @Return:
     256        <nothing>
     257    '''
     258    import tarfile
     259    from glob import glob
     260
     261    print('Create tarball ...')
     262
     263    # change to FLEXEXTRACT directory so that the tar can contain
     264    # relative pathes to the files and directories
     265    ecd = _config.PATH_FLEXEXTRACT_DIR + '/'
     266    os.chdir(ecd)
     267
     268    # get lists of the files to be added to the tar file
     269    ECMWF_ENV_FILE = [_config.PATH_RELATIVE_ECMWF_ENV]
     270    pyfiles = [os.path.relpath(x, ecd)
     271               for x in glob(_config.PATH_LOCAL_PYTHON +
     272                             os.path.sep + '*py')]
     273    controlfiles = [os.path.relpath(x, ecd)
     274                    for x in glob(_config.PATH_CONTROLFILES +
     275                                  os.path.sep + 'CONTROL*')]
     276    tempfiles = [os.path.relpath(x, ecd)
     277                 for x in glob(_config.PATH_TEMPLATES +
     278                               os.path.sep + '*')]
     279    ffiles = [os.path.relpath(x, ecd)
     280              for x in glob(_config.PATH_FORTRAN_SRC +
     281                            os.path.sep + '*.f*')]
     282    hfiles = [os.path.relpath(x, ecd)
     283              for x in glob(_config.PATH_FORTRAN_SRC +
     284                            os.path.sep + '*.h')]
     285    makefiles = [os.path.relpath(x, ecd)
     286                 for x in glob(_config.PATH_FORTRAN_SRC +
     287                               os.path.sep + 'Makefile*')]
     288
     289    # concatenate single lists to one for a better looping
     290    filelist = pyfiles + controlfiles + tempfiles + ffiles + hfiles + \
     291               makefiles + ECMWF_ENV_FILE
     292
     293    # create installation tar-file
    257294    try:
    258         subprocess.check_call(['tar -cvf '+
    259                                ecd + '../' + tarname + ' ' +
    260                                ecd + 'python/*py ' +
    261                                ecd + 'python/CONTROL* ' +
    262                                ecd + 'python/*ksh ' +
    263                                ecd + 'python/*temp* ' +
    264                                ecd + 'python/ECMWF_ENV ' +
    265                                ecd + '_templates ' +
    266                                ecd + 'src/*.f ' +
    267                                ecd + 'src/*.f90 ' +
    268                                ecd + 'src/*.h ' +
    269                                ecd + 'src/Makefile*'], shell=True)
     295        with tarfile.open(tarball_path, "w:gz") as tar_handle:
     296            for file in filelist:
     297                tar_handle.add(file)
     298
    270299    except subprocess.CalledProcessError as e:
    271         print 'ERROR:'
    272         print e.output
    273         sys.exit('could not make installation tar ball!')
    274 
    275     return
    276 
    277 def mk_env_vars(ecd, ecuid, ecgid, gateway, destination):
     300        print('... ERROR CODE:\n ... ' + str(e.returncode))
     301        print('... ERROR MESSAGE:\n ... ' + str(e))
     302
     303        sys.exit('... could not make installation tar ball!')
     304
     305    return
     306
     307
     308def un_tarball(tarball_path):
     309    '''
     310    @Description:
     311        Extracts the given tarball into current directory.
     312
     313    @Input:
     314        tarball_path: string
     315            The complete path to the tar file which will contain all
     316            relevant data for flex_extract.
     317
     318    @Return:
     319        <nothing>
     320    '''
     321    import tarfile
     322
     323    print('Untar ...')
     324
     325    with tarfile.open(tarball_path) as tar_handle:
     326        tar_handle.extractall()
     327
     328    return
     329
     330def mk_env_vars(ecuid, ecgid, gateway, destination):
    278331    '''
    279332    @Description:
     
    282335
    283336    @Input:
    284         ecd: string
    285             The path were the file is to be stored.
    286 
    287337        ecuid: string
    288338            The user id on ECMWF server.
     
    302352    '''
    303353
    304     with open(ecd + 'python/ECMWF_ENV', 'w') as fo:
     354    with open(_config.PATH_RELATIVE_ECMWF_ENV, 'w') as fo:
    305355        fo.write('ECUID ' + ecuid + '\n')
    306356        fo.write('ECGID ' + ecgid + '\n')
     
    310360    return
    311361
    312 def mk_compilejob(template, makefile, target, ecuid, ecgid, fp_root):
     362def mk_compilejob(makefile, target, ecuid, ecgid, fp_root):
    313363    '''
    314364    @Description:
     
    318368
    319369    @Input:
    320         template: string
    321             File which contains the original text for the job template.
    322             It must contain the complete path to the file.
    323 
    324370        makefile: string
    325371            Name of the makefile which should be used to compile FORTRAN
     
    343389    '''
    344390
     391    template = os.path.join(_config.PATH_RELATIVE_TEMPLATES,
     392                            _config.TEMPFILE_INSTALL_COMPILEJOB)
    345393    with open(template) as f:
    346394        fdata = f.read().split('\n')
    347395
    348     with open(template[:-4] + 'ksh', 'w') as fo:
     396    compilejob = os.path.join(_config.PATH_RELATIVE_JOBSCRIPTS,
     397                              _config.FILE_INSTALL_COMPILEJOB)
     398    with open(compilejob, 'w') as fo:
    349399        for data in fdata:
    350400            if 'MAKEFILE=' in data:
     
    371421    return
    372422
    373 def mk_job_template(template, ecuid, ecgid, gateway, destination, fp_root):
     423def mk_job_template(ecuid, ecgid, gateway, destination, fp_root):
    374424    '''
    375425    @Description:
    376426        Modifies the original job template file so that it is specified
    377427        for the user and the environment were it will be applied. Result
    378         is stored in a new file "job.temp" in the python directory.
    379 
    380     @Input:
    381         template: string
    382             File which contains the original text for the job template.
    383             It must contain the complete path to the file.
    384 
     428        is stored in a new file.
     429
     430    @Input:
    385431        ecuid: string
    386432            The user id on ECMWF server.
     
    403449        <nothing>
    404450    '''
    405 
     451    fp_root_path_to_python = os.path.join(fp_root, _config.FLEXEXTRACT_DIRNAME,
     452                         _config.PATH_RELATIVE_PYTHON)
     453
     454    template = os.path.join(_config.PATH_RELATIVE_TEMPLATES,
     455                            _config.TEMPFILE_INSTALL_JOB)
    406456    with open(template) as f:
    407457        fdata = f.read().split('\n')
    408458
    409     with open(template[:-2], 'w') as fo:
     459    jobfile_temp = os.path.join(_config.PATH_RELATIVE_TEMPLATES,
     460                                _config.TEMPFILE_JOB)
     461    with open(jobfile_temp, 'w') as fo:
    410462        for data in fdata:
    411463            if '--workdir' in data:
    412                 data = '#SBATCH --workdir=/scratch/ms/' + ecgid + \
    413                         '/' + ecuid
     464                data = '#SBATCH --workdir=/scratch/ms/' + ecgid + '/' + ecuid
    414465            elif '##PBS -o' in data:
    415466                data = '##PBS -o /scratch/ms/' + ecgid + '/' + \
    416467                        ecuid + 'flex_ecmwf.$Jobname.$Job_ID.out'
    417468            elif  'export PATH=${PATH}:' in data:
    418                 data += fp_root + '/flex_extract_v7.1/python'
     469                data += fp_root_path_to_python
    419470
    420471            fo.write(data + '\n')
    421472    return
    422473
    423 def delete_convert_build(ecd):
     474def delete_convert_build(src_path):
    424475    '''
    425476    @Description:
     
    428479
    429480    @Input:
    430         ecd: string
    431             The path to the Fortran program.
    432 
    433     @Return:
    434         <nothing>
    435     '''
    436 
    437     modfiles = UioFiles(ecd, '*.mod')
    438     objfiles = UioFiles(ecd, '*.o')
    439     exefile = UioFiles(ecd, 'CONVERT2')
     481        src_path: string
     482            Path to the fortran source directory.
     483
     484    @Return:
     485        <nothing>
     486    '''
     487
     488    modfiles = UioFiles(src_path, '*.mod')
     489    objfiles = UioFiles(src_path, '*.o')
     490    exefile = UioFiles(src_path, _config.FORTRAN_EXECUTABLE)
    440491
    441492    modfiles.delete_files()
     
    445496    return
    446497
    447 def make_convert_build(ecd, makefile, f_executable):
     498def make_convert_build(src_path, makefile):
    448499    '''
    449500    @Description:
     
    451502
    452503    @Input:
    453         ecd: string
    454             The path were the file is to be stored.
     504        src_path: string
     505            Path to the fortran source directory.
    455506
    456507        makefile: string
    457508            The name of the makefile which should be used.
    458509
    459         f_executable: string
    460             The name of the executable the Fortran program generates after
    461             compilation.
    462 
    463510    @Return:
    464511        <nothing>
     
    466513
    467514    try:
    468         print 'Using makefile: ' + makefile
    469         p = subprocess.Popen(['make', '-f', ecd + makefile],
     515        print('Using makefile: ' + makefile)
     516        p = subprocess.Popen(['make', '-f',
     517                              os.path.join(src_path, makefile)],
    470518                             stdin=subprocess.PIPE,
    471519                             stdout=subprocess.PIPE,
     
    473521                             bufsize=1)
    474522        pout, perr = p.communicate()
    475         print pout
     523        print(pout)
    476524        if p.returncode != 0:
    477             print perr
    478             print 'Please edit ' + makefile + \
    479                   ' or try another Makefile in the src directory.'
    480             print 'Most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB ' \
    481                   'and EMOSLIB must be adapted.'
    482             print 'Available Makefiles:'
    483             print UioFiles('.', 'Makefile*')
     525            print(perr)
     526            print('Please edit ' + makefile +
     527                  ' or try another Makefile in the src directory.')
     528            print('Most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB '
     529                  'and EMOSLIB must be adapted.')
     530            print('Available Makefiles:')
     531            print(UioFiles(src_path, 'Makefile*'))
    484532            sys.exit('Compilation failed!')
    485533    except ValueError as e:
    486         print 'ERROR: Makefile call failed:'
    487         print e
     534        print('ERROR: Makefile call failed:')
     535        print(e)
    488536    else:
    489         subprocess.check_call(['ls', '-l', ecd + f_executable])
     537        subprocess.check_call(['ls', '-l',
     538                               os.path.join(src_path,
     539                                            _config.FORTRAN_EXECUTABLE)])
    490540
    491541    return
Note: See TracChangeset for help on using the changeset viewer.
hosted by ZAMG