source: flex_extract.git/Source/Python/install.py @ 3e13e02

ctbtodev
Last change on this file since 3e13e02 was a916e8f, checked in by Anne Philipp <anne.philipp@…>, 4 years ago

ECMWF server output directory renamed; reformulate dapoly formula; changed template filenames; make use of config jobscript names

  • Property mode set to 100755
File size: 24.2 KB
RevLine 
[8463d78]1#!/usr/bin/env python3
[64cf353]2# -*- coding: utf-8 -*-
[991df6a]3#*******************************************************************************
4# @Author: Leopold Haimberger (University of Vienna)
5#
6# @Date: November 2015
7#
8# @Change History:
9#
10#    February 2018 - Anne Philipp (University of Vienna):
11#        - applied PEP8 style guide
12#        - added documentation
[ff99eae]13#        - moved install_args_and_control in here
[2fb99de]14#        - splitted code in smaller functions
[5f67883]15#        - delete fortran build files in here instead of compile job script
[6f951ca]16#        - changed static path names to variables from config file
17#        - splitted install function into several smaller pieces
18#        - use of tarfile package in python
[a916e8f]19#    June 2020 - Anne Philipp
20#        - renamed "convert" functions to "fortran" functions
21#        - reconfigured mk_tarball to select *.template files instead
22#          of *.nl and *.temp
23#        - added check for makefile settings
[991df6a]24#
25# @License:
[026b359]26#    (C) Copyright 2014-2020.
[6f951ca]27#    Anne Philipp, Leopold Haimberger
[991df6a]28#
[44174de]29#    SPDX-License-Identifier: CC-BY-4.0
30#
[6f951ca]31#    This work is licensed under the Creative Commons Attribution 4.0
32#    International License. To view a copy of this license, visit
33#    http://creativecommons.org/licenses/by/4.0/ or send a letter to
34#    Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
[991df6a]35#
[6f951ca]36# @Methods:
37#    main
38#    get_install_cmdline_args
39#    install_via_gateway
40#    check_install_conditions
41#    mk_tarball
42#    un_tarball
43#    mk_env_vars
44#    mk_compilejob
45#    mk_job_template
[5f67883]46#    del_fortran_build
47#    mk_fortran_build
[991df6a]48#
49#*******************************************************************************
[6f951ca]50'''This script installs the flex_extract program.
51
52Depending on the selected installation environment (locally or on the
53ECMWF server ecgate or cca) the program extracts the commandline
54arguments and the CONTROL file parameter and prepares the corresponding
55environment.
56The necessary files are collected in a tar-ball and placed
57at the target location. There its untared, the environment variables will
58be set and the Fortran code will be compiled.
59If the ECMWF environment is selected a job script is prepared and submitted
60for the remaining configurations after putting the tar-ball to the
61target ECMWF server.
62
63Type: install.py --help
64to get information about command line parameters.
65Read the documentation for usage instructions.
66'''
[991df6a]67
[64cf353]68# ------------------------------------------------------------------------------
69# MODULES
70# ------------------------------------------------------------------------------
[8ce3be6]71from __future__ import print_function
72
[991df6a]73import os
74import sys
[d69b677]75import subprocess
[3946de5]76import tarfile
[ff99eae]77from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
[991df6a]78
79# software specific classes and modules from flex_extract
[2fb99de]80import _config
[ba99230]81from Classes.ControlFile import ControlFile
82from Classes.UioFiles import UioFiles
83from Mods.tools import (make_dir, put_file_to_ecserver, submit_job_to_ecserver,
[8ce3be6]84                        silent_remove, execute_subprocess, none_or_str)
[d69b677]85
[64cf353]86# ------------------------------------------------------------------------------
87# FUNCTIONS
88# ------------------------------------------------------------------------------
[991df6a]89def main():
[274f9ef]90    '''Controls the installation process. Calls the installation function
91    if target is specified.
[991df6a]92
[274f9ef]93    Parameters
94    ----------
[991df6a]95
[274f9ef]96    Return
97    ------
[991df6a]98    '''
99
[8652e7e]100    args = get_install_cmdline_args()
[4971f63]101    c = ControlFile(args.controlfile)
[54a8a01]102    c.assign_args_to_control(args)
[6cda7c1]103    check_install_conditions(c)
[991df6a]104
[8ce3be6]105    if c.install_target.lower() != 'local': # ecgate or cca
106        install_via_gateway(c)
107    else: # local
108        install_local(c)
[991df6a]109
[54a8a01]110    return
[991df6a]111
[8652e7e]112def get_install_cmdline_args():
[274f9ef]113    '''Decomposes the command line arguments and assigns them to variables.
114    Apply default values for non mentioned arguments.
[efdb01a]115
[274f9ef]116    Parameters
117    ----------
[efdb01a]118
[274f9ef]119    Return
120    ------
[6f951ca]121    args : Namespace
[274f9ef]122        Contains the commandline arguments from script/program call.
[efdb01a]123    '''
[8ce3be6]124    parser = ArgumentParser(description='Install flex_extract software '
125                                        'locally or on ECMWF machines',
[efdb01a]126                            formatter_class=ArgumentDefaultsHelpFormatter)
127
[8ce3be6]128    parser.add_argument('--target', dest='install_target',
129                        type=none_or_str, default=None,
[efdb01a]130                        help="Valid targets: local | ecgate | cca , \
131                        the latter two are at ECMWF")
[8ce3be6]132    parser.add_argument("--makefile", dest="makefile",
133                        type=none_or_str, default=None,
134                        help='Name of Makefile to use for compiling the '
135                        'Fortran program')
136    parser.add_argument("--ecuid", dest="ecuid",
137                        type=none_or_str, default=None,
138                        help='The user id at ECMWF.')
139    parser.add_argument("--ecgid", dest="ecgid",
140                        type=none_or_str, default=None,
141                        help='The group id at ECMWF.')
142    parser.add_argument("--gateway", dest="gateway",
143                        type=none_or_str, default=None,
144                        help='The name of the local gateway server.')
145    parser.add_argument("--destination", dest="destination",
146                        type=none_or_str, default=None,
147                        help='The ecaccess association, e.g. '
148                        'myUser@genericSftp')
149
150    parser.add_argument("--installdir", dest="installdir",
151                        type=none_or_str, default=None,
152                        help='Root directory where '
153                        'flex_extract will be installed to.')
[efdb01a]154
[54a8a01]155    # arguments for job submission to ECMWF, only needed by submit.py
[efdb01a]156    parser.add_argument("--job_template", dest='job_template',
[8ce3be6]157                        type=none_or_str, default="job.template",
158                        help='The rudimentary template file to create a batch '
159                        'job template for submission to ECMWF servers.')
[efdb01a]160
161    parser.add_argument("--controlfile", dest="controlfile",
[8ce3be6]162                        type=none_or_str, default='CONTROL_EA5',
163                        help="The file with all CONTROL parameters.")
[efdb01a]164
165    args = parser.parse_args()
166
[54a8a01]167    return args
168
[efdb01a]169
[54a8a01]170def install_via_gateway(c):
[8ce3be6]171    '''Prepare data transfer to remote gate and submit a job script which will
[274f9ef]172    install everything on the remote gate.
173
174    Parameters
175    ----------
[6f951ca]176    c : ControlFile
[274f9ef]177        Contains all the parameters of CONTROL file and
178        command line.
179
180    Return
181    ------
182
[54a8a01]183    '''
[2fb99de]184
185    tarball_name = _config.FLEXEXTRACT_DIRNAME + '.tar'
[8ce3be6]186    tar_file = os.path.join(_config.PATH_FLEXEXTRACT_DIR, tarball_name)
[54a8a01]187
[0f89116]188    mk_compilejob(c.makefile, c.ecuid, c.ecgid, c.installdir)
[54a8a01]189
[0f89116]190    mk_job_template(c.ecuid, c.ecgid, c.installdir)
[8ce3be6]191
192    mk_env_vars(c.ecuid, c.ecgid, c.gateway, c.destination)
193
194    mk_tarball(tar_file, c.install_target)
195
196    put_file_to_ecserver(_config.PATH_FLEXEXTRACT_DIR, tarball_name,
197                         c.install_target, c.ecuid, c.ecgid)
198
199    submit_job_to_ecserver(c.install_target,
200                           os.path.join(_config.PATH_REL_JOBSCRIPTS,
201                                        _config.FILE_INSTALL_COMPILEJOB))
202
203    silent_remove(tar_file)
204
205    print('Job compilation script has been submitted to ecgate for ' +
206          'installation in ' + c.installdir +
[0f89116]207          '/' + _config.FLEXEXTRACT_DIRNAME)
[8ce3be6]208    print('You should get an email with subject "flexcompile" within ' +
209          'the next few minutes!')
210
211    return
212
213def install_local(c):
214    '''Perform the actual installation on a local machine.
[54a8a01]215
[8ce3be6]216    Parameters
217    ----------
218    c : ControlFile
219        Contains all the parameters of CONTROL file and
220        command line.
221
222    Return
223    ------
224
225    '''
226
227    tar_file = os.path.join(_config.PATH_FLEXEXTRACT_DIR,
228                            _config.FLEXEXTRACT_DIRNAME + '.tar')
229
[0f89116]230    if c.installdir == _config.PATH_FLEXEXTRACT_DIR:
[8ce3be6]231        print('WARNING: installdir has not been specified')
232        print('flex_extract will be installed in here by compiling the ' +
233              'Fortran source in ' + _config.PATH_FORTRAN_SRC)
234        os.chdir(_config.PATH_FORTRAN_SRC)
235    else: # creates the target working directory for flex_extract
236        c.installdir = os.path.expandvars(os.path.expanduser(
237            c.installdir))
238        if os.path.abspath(_config.PATH_FLEXEXTRACT_DIR) != \
239           os.path.abspath(c.installdir):
240            mk_tarball(tar_file, c.install_target)
241            make_dir(os.path.join(c.installdir,
[0f89116]242                                  _config.FLEXEXTRACT_DIRNAME))
[8ce3be6]243            os.chdir(os.path.join(c.installdir,
[0f89116]244                                  _config.FLEXEXTRACT_DIRNAME))
[8ce3be6]245            un_tarball(tar_file)
246            os.chdir(os.path.join(c.installdir,
[0f89116]247                                  _config.FLEXEXTRACT_DIRNAME,
[8ce3be6]248                                  _config.PATH_REL_FORTRAN_SRC))
249
[5f67883]250    # Create Fortran executable
[8ce3be6]251    print('Install ' +  _config.FLEXEXTRACT_DIRNAME + ' software at ' +
252          c.install_target + ' in directory ' +
253          os.path.abspath(c.installdir) + '\n')
254
[5f67883]255    del_fortran_build('.')
256    mk_fortran_build('.', c.makefile)
[8ce3be6]257
258    os.chdir(_config.PATH_FLEXEXTRACT_DIR)
259    if os.path.isfile(tar_file):
260        os.remove(tar_file)
[54a8a01]261
262    return
263
[8ce3be6]264
[6cda7c1]265def check_install_conditions(c):
266    '''Checks a couple of necessary attributes and conditions
267    for the installation such as if they exist and contain values.
268    Otherwise set default values.
269
270    Parameters
271    ----------
[6f951ca]272    c : ControlFile
[6cda7c1]273        Contains all the parameters of CONTROL file and
274        command line.
275
276
277    Return
278    ------
279
280    '''
281
282    if c.install_target and \
283       c.install_target not in _config.INSTALL_TARGETS:
284        print('ERROR: unknown or missing installation target ')
285        print('target: ', c.install_target)
286        print('please specify correct installation target ' +
[0f89116]287              str(_config.INSTALL_TARGETS))
[6cda7c1]288        print('use -h or --help for help')
289        sys.exit(1)
290
291    if c.install_target and c.install_target != 'local':
[50f9ca6]292        if not c.ecgid or not c.ecuid:
293            print('Please enter your ECMWF user id and group id '
294                  ' with command line options --ecuid --ecgid')
[6cda7c1]295            print('Try "' + sys.argv[0].split('/')[-1] + \
296                  ' -h" to print usage information')
[50f9ca6]297            print('Please consult ecaccess documentation or ECMWF user '
298                  'support for further details.\n')
[6cda7c1]299            sys.exit(1)
[50f9ca6]300        if not c.gateway or not c.destination:
301            print('WARNING: Parameters GATEWAY and DESTINATION were '
302                  'not properly set for working on ECMWF server. \n'
303                  'There will be no transfer of output files to the '
304                  'local gateway server possible!')
[8ce3be6]305        if not c.installdir:
306            c.installdir = '${HOME}'
[6cda7c1]307    else: # local
[8ce3be6]308        if not c.installdir:
309            c.installdir = _config.PATH_FLEXEXTRACT_DIR
[6cda7c1]310
[5f67883]311    if not c.makefile:
312        print('WARNING: no makefile was specified.')
313        if c.install_target == 'local':
314            c.makefile = 'makefile_local_gfortran'
315            print('WARNING: default makefile selected: makefile_local_gfortan')
316        elif c.install_target == 'ecgate':
317            c.makefile = 'makefile_ecgate'
318            print('WARNING: default makefile selected: makefile_ecgate')
319        elif c.install_target == 'cca' or \
320             c.install_target == 'ccb':
321            c.makefile = 'makefile_cray'
322            print('WARNING: default makefile selected: makefile_cray')
323        else:
324            pass
325       
[6cda7c1]326    return
327
328
[25b14be]329def mk_tarball(tarball_path, target):
[274f9ef]330    '''Creates a tarball with all necessary files which need to be sent to the
331    installation directory.
332    It does not matter if this is local or remote.
333    Collects all python files, the Fortran source and makefiles,
334    the ECMWF_ENV file, the CONTROL files as well as the
335    template files.
336
337    Parameters
338    ----------
[6f951ca]339    tarball_path : str
[274f9ef]340        The complete path to the tar file which will contain all
341        relevant data for flex_extract.
342
[6f951ca]343    target : str
[274f9ef]344        The queue where the job is submitted to.
345
346    Return
347    ------
348
[54a8a01]349    '''
[2fb99de]350
351    print('Create tarball ...')
352
353    # change to FLEXEXTRACT directory so that the tar can contain
354    # relative pathes to the files and directories
355    ecd = _config.PATH_FLEXEXTRACT_DIR + '/'
356    os.chdir(ecd)
357
358    # get lists of the files to be added to the tar file
[25b14be]359    if target == 'local':
[0f89116]360        ecmwf_env_file = []
[3946de5]361        runfile = [os.path.relpath(x, ecd)
362                   for x in UioFiles(_config.PATH_REL_RUN_DIR,
363                                     'run_local.sh').files]
[25b14be]364    else:
[0f89116]365        ecmwf_env_file = [_config.PATH_REL_ECMWF_ENV]
[3946de5]366        runfile = [os.path.relpath(x, ecd)
[0f89116]367                   for x in UioFiles(_config.PATH_REL_RUN_DIR,
368                                     'run.sh').files]
[25b14be]369
[2fb99de]370    pyfiles = [os.path.relpath(x, ecd)
[3946de5]371               for x in UioFiles(_config.PATH_REL_PYTHON_SRC, '*py').files]
372    pytestfiles = [os.path.relpath(x, ecd)
[0f89116]373                   for x in UioFiles(_config.PATH_REL_PYTHONTEST_SRC, '*py').files]
[2fb99de]374    controlfiles = [os.path.relpath(x, ecd)
[3946de5]375                    for x in UioFiles(_config.PATH_REL_CONTROLFILES,
[25b14be]376                                      'CONTROL*').files]
[1eca806]377    testfiles = [os.path.relpath(x, ecd)
[0f89116]378                 for x in UioFiles(_config.PATH_REL_TEST, '*').files]
[2fb99de]379    tempfiles = [os.path.relpath(x, ecd)
[a916e8f]380                 for x in UioFiles(_config.PATH_REL_TEMPLATES, '*.template').files]
[3946de5]381    gribtable = [os.path.relpath(x, ecd)
[0f89116]382                 for x in UioFiles(_config.PATH_REL_TEMPLATES, '*grib*').files]
[2fb99de]383    ffiles = [os.path.relpath(x, ecd)
[0f89116]384              for x in UioFiles(_config.PATH_REL_FORTRAN_SRC, '*.f90').files]
[2fb99de]385    hfiles = [os.path.relpath(x, ecd)
[3946de5]386              for x in UioFiles(_config.PATH_REL_FORTRAN_SRC, '*.h').files]
[2fb99de]387    makefiles = [os.path.relpath(x, ecd)
[3a41083]388                 for x in UioFiles(_config.PATH_REL_FORTRAN_SRC, 'makefile*').files]
[3946de5]389    jobdir = [_config.PATH_REL_JOBSCRIPTS]
[2fb99de]390
391    # concatenate single lists to one for a better looping
[a916e8f]392    filelist = pyfiles + pytestfiles + controlfiles + tempfiles + \
[0f89116]393               ffiles + gribtable + hfiles + makefiles + ecmwf_env_file + \
[1eca806]394               runfile + jobdir + testfiles +\
[3946de5]395               ['CODE_OF_CONDUCT.md', 'LICENSE.md', 'README.md']
[2fb99de]396
397    # create installation tar-file
[0f89116]398    exclude_files = [".ksh", ".tar"]
[54a8a01]399    try:
[2fb99de]400        with tarfile.open(tarball_path, "w:gz") as tar_handle:
[0f89116]401            for filename in filelist:
402                tar_handle.add(filename, recursive=False,
[3946de5]403                               filter=lambda tarinfo: None
[0f89116]404                               if os.path.splitext(tarinfo.name)[1]
405                               in exclude_files
406                               else tarinfo)
[79729d5]407    except tarfile.TarError as e:
[0f89116]408        print('... ERROR: ' + str(e))
409
[79729d5]410        sys.exit('\n... error occured while trying to create the tar-file ' +
[0f89116]411                 str(tarball_path))
[54a8a01]412
413    return
414
[2fb99de]415
416def un_tarball(tarball_path):
[274f9ef]417    '''Extracts the given tarball into current directory.
[2fb99de]418
[274f9ef]419    Parameters
420    ----------
[6f951ca]421    tarball_path : str
[274f9ef]422        The complete path to the tar file which will contain all
423        relevant data for flex_extract.
424
425    Return
426    ------
[2fb99de]427
428    '''
429
430    print('Untar ...')
431
[3946de5]432    try:
433        with tarfile.open(tarball_path) as tar_handle:
434            tar_handle.extractall()
435    except tarfile.TarError as e:
436        sys.exit('\n... error occured while trying to read tar-file ' +
[0f89116]437                 str(tarball_path))
[3946de5]438    except OSError as e:
439        print('... ERROR CODE: ' + str(e.errno))
440        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
441
442        sys.exit('\n... error occured while trying to read tar-file ' +
443                 str(tarball_path))
[2fb99de]444
445    return
446
447def mk_env_vars(ecuid, ecgid, gateway, destination):
[274f9ef]448    '''Creates a file named ECMWF_ENV which contains the
449    necessary environmental variables at ECMWF servers.
450    It is based on the template ECMWF_ENV.template.
451
452    Parameters
453    ----------
[6f951ca]454    ecuid : str
[274f9ef]455        The user id on ECMWF server.
[54a8a01]456
[6f951ca]457    ecgid : str
[274f9ef]458        The group id on ECMWF server.
[54a8a01]459
[6f951ca]460    gateway : str
[274f9ef]461        The gateway server the user is using.
[54a8a01]462
[6f951ca]463    destination : str
[274f9ef]464        The remote destination which is used to transfer files
465        from ECMWF server to local gateway server.
[54a8a01]466
[274f9ef]467    Return
468    ------
[54a8a01]469
470    '''
[0aaeb04]471    from genshi.template.text import NewTextTemplate
472    from genshi.template import  TemplateLoader
[3946de5]473    from genshi.template.eval import UndefinedError
[54a8a01]474
[3946de5]475    try:
476        loader = TemplateLoader(_config.PATH_TEMPLATES, auto_reload=False)
477        ecmwfvars_template = loader.load(_config.TEMPFILE_USER_ENVVARS,
478                                         cls=NewTextTemplate)
479
[0f89116]480        stream = ecmwfvars_template.generate(user_name=ecuid,
481                                             user_group=ecgid,
482                                             gateway_name=gateway,
483                                             destination_name=destination
484                                            )
[3946de5]485    except UndefinedError as e:
486        print('... ERROR ' + str(e))
487
488        sys.exit('\n... error occured while trying to generate template ' +
489                 _config.PATH_ECMWF_ENV)
490    except OSError as e:
491        print('... ERROR CODE: ' + str(e.errno))
492        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
493
494        sys.exit('\n... error occured while trying to generate template ' +
495                 _config.PATH_ECMWF_ENV)
[0aaeb04]496
[3946de5]497    try:
498        with open(_config.PATH_ECMWF_ENV, 'w') as f:
499            f.write(stream.render('text'))
500    except OSError as e:
501        print('... ERROR CODE: ' + str(e.errno))
502        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
[0aaeb04]503
[3946de5]504        sys.exit('\n... error occured while trying to write ' +
505                 _config.PATH_ECMWF_ENV)
[54a8a01]506
507    return
508
[0f89116]509def mk_compilejob(makefile, ecuid, ecgid, fp_root):
[274f9ef]510    '''Modifies the original job template file so that it is specified
511    for the user and the environment were it will be applied. Result
512    is stored in a new file "job.temp" in the python directory.
513
514    Parameters
515    ----------
[6f951ca]516    makefile : str
[274f9ef]517        Name of the makefile which should be used to compile FORTRAN
[5f67883]518        program.
[54a8a01]519
[6f951ca]520    ecuid : str
[274f9ef]521        The user id on ECMWF server.
[54a8a01]522
[6f951ca]523    ecgid : str
[274f9ef]524        The group id on ECMWF server.
[54a8a01]525
[6f951ca]526    fp_root : str
[274f9ef]527       Path to the root directory of FLEXPART environment or flex_extract
528       environment.
[54a8a01]529
[274f9ef]530    Return
531    ------
[a4b6cef]532
[991df6a]533    '''
[0aaeb04]534    from genshi.template.text import NewTextTemplate
535    from genshi.template import  TemplateLoader
[3946de5]536    from genshi.template.eval import  UndefinedError
[0aaeb04]537
538    if fp_root == '../':
539        fp_root = '$HOME'
540
[3946de5]541    try:
542        loader = TemplateLoader(_config.PATH_TEMPLATES, auto_reload=False)
543        compile_template = loader.load(_config.TEMPFILE_INSTALL_COMPILEJOB,
544                                       cls=NewTextTemplate)
545
546        stream = compile_template.generate(
[0f89116]547            usergroup=ecgid,
548            username=ecuid,
549            version_number=_config._VERSION_STR,
550            fp_root_scripts=fp_root,
551            makefile=makefile,
552            fortran_program=_config.FORTRAN_EXECUTABLE
[3946de5]553        )
554    except UndefinedError as e:
555        print('... ERROR ' + str(e))
556
557        sys.exit('\n... error occured while trying to generate template ' +
558                 _config.TEMPFILE_INSTALL_COMPILEJOB)
559    except OSError as e:
560        print('... ERROR CODE: ' + str(e.errno))
561        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
562
563        sys.exit('\n... error occured while trying to generate template ' +
564                 _config.TEMPFILE_INSTALL_COMPILEJOB)
[0aaeb04]565
[3946de5]566    try:
567        compilejob = os.path.join(_config.PATH_JOBSCRIPTS,
568                                  _config.FILE_INSTALL_COMPILEJOB)
[0aaeb04]569
[3946de5]570        with open(compilejob, 'w') as f:
571            f.write(stream.render('text'))
572    except OSError as e:
573        print('... ERROR CODE: ' + str(e.errno))
574        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
575
576        sys.exit('\n... error occured while trying to write ' +
577                 compilejob)
[0aaeb04]578
[54a8a01]579    return
580
[0f89116]581def mk_job_template(ecuid, ecgid, fp_root):
[274f9ef]582    '''Modifies the original job template file so that it is specified
583    for the user and the environment were it will be applied. Result
584    is stored in a new file.
[54a8a01]585
[274f9ef]586    Parameters
587    ----------
[6f951ca]588    ecuid : str
[274f9ef]589        The user id on ECMWF server.
[54a8a01]590
[6f951ca]591    ecgid : str
[274f9ef]592        The group id on ECMWF server.
[54a8a01]593
[6f951ca]594    fp_root : str
[274f9ef]595       Path to the root directory of FLEXPART environment or flex_extract
596       environment.
597
598    Return
599    ------
[54a8a01]600
601    '''
[c5074d2]602    from genshi.template.text import NewTextTemplate
603    from genshi.template import  TemplateLoader
[3946de5]604    from genshi.template.eval import  UndefinedError
[c5074d2]605
606    fp_root_path_to_python = os.path.join(fp_root,
607                                          _config.FLEXEXTRACT_DIRNAME,
[3946de5]608                                          _config.PATH_REL_PYTHON_SRC)
[ff2a11c]609    if '$' in fp_root_path_to_python:
610        ind = fp_root_path_to_python.index('$')
611        fp_root_path_to_python = fp_root_path_to_python[0:ind] + '$' + \
612                                 fp_root_path_to_python[ind:]
[3946de5]613
614    try:
615        loader = TemplateLoader(_config.PATH_TEMPLATES, auto_reload=False)
616        compile_template = loader.load(_config.TEMPFILE_INSTALL_JOB,
617                                       cls=NewTextTemplate)
618
619        stream = compile_template.generate(
[0f89116]620            usergroup=ecgid,
621            username=ecuid,
622            version_number=_config._VERSION_STR,
623            fp_root_path=fp_root_path_to_python,
[3946de5]624        )
625    except UndefinedError as e:
626        print('... ERROR ' + str(e))
[c5074d2]627
[3946de5]628        sys.exit('\n... error occured while trying to generate template ' +
629                 _config.TEMPFILE_INSTALL_JOB)
630    except OSError as e:
631        print('... ERROR CODE: ' + str(e.errno))
632        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
633
634        sys.exit('\n... error occured while trying to generate template ' +
635                 _config.TEMPFILE_INSTALL_JOB)
636
637
638    try:
639        tempjobfile = os.path.join(_config.PATH_TEMPLATES,
640                                   _config.TEMPFILE_JOB)
[c5074d2]641
[3946de5]642        with open(tempjobfile, 'w') as f:
643            f.write(stream.render('text'))
644    except OSError as e:
645        print('... ERROR CODE: ' + str(e.errno))
646        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
[c5074d2]647
[3946de5]648        sys.exit('\n... error occured while trying to write ' +
649                 tempjobfile)
[c5074d2]650
[54a8a01]651    return
652
[5f67883]653def del_fortran_build(src_path):
[274f9ef]654    '''Clean up the Fortran source directory and remove all
[5f67883]655    build files (e.g. \*.o, \*.mod and FORTRAN EXECUTABLE)
[274f9ef]656
657    Parameters
658    ----------
[6f951ca]659    src_path : str
[274f9ef]660        Path to the fortran source directory.
[54a8a01]661
[274f9ef]662    Return
663    ------
[54a8a01]664
665    '''
666
[2fb99de]667    modfiles = UioFiles(src_path, '*.mod')
668    objfiles = UioFiles(src_path, '*.o')
669    exefile = UioFiles(src_path, _config.FORTRAN_EXECUTABLE)
[54a8a01]670
671    modfiles.delete_files()
672    objfiles.delete_files()
673    exefile.delete_files()
674
675    return
676
[5f67883]677def mk_fortran_build(src_path, makefile):
[274f9ef]678    '''Compiles the Fortran code and generates the executable.
679
680    Parameters
681    ----------
[6f951ca]682    src_path : str
[274f9ef]683        Path to the fortran source directory.
[54a8a01]684
[6f951ca]685    makefile : str
[274f9ef]686        The name of the makefile which should be used.
[54a8a01]687
[274f9ef]688    Return
689    ------
[54a8a01]690
691    '''
692
693    try:
[2fb99de]694        print('Using makefile: ' + makefile)
695        p = subprocess.Popen(['make', '-f',
696                              os.path.join(src_path, makefile)],
[54a8a01]697                             stdin=subprocess.PIPE,
698                             stdout=subprocess.PIPE,
699                             stderr=subprocess.PIPE,
700                             bufsize=1)
701        pout, perr = p.communicate()
[79729d5]702        print(pout.decode())
[54a8a01]703        if p.returncode != 0:
[79729d5]704            print(perr.decode())
[2fb99de]705            print('Please edit ' + makefile +
[5f67883]706                  ' or try another makefile in the src directory.')
707            print('Most likely ECCODES_INCLUDE_DIR, ECCODES_LIB '
[2fb99de]708                  'and EMOSLIB must be adapted.')
[5f67883]709            print('Available makefiles:')
710            print(UioFiles(src_path, 'makefile*'))
[54a8a01]711            sys.exit('Compilation failed!')
712    except ValueError as e:
[5f67883]713        print('ERROR: makefile call failed:')
[2fb99de]714        print(e)
[d69b677]715    else:
[0f89116]716        execute_subprocess(['ls', '-l',
717                            os.path.join(src_path, _config.FORTRAN_EXECUTABLE)],
718                           error_msg='FORTRAN EXECUTABLE COULD NOT BE FOUND!')
[a4b6cef]719
[d69b677]720    return
721
[a4b6cef]722
[d69b677]723if __name__ == "__main__":
724    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG