File: configure_transform.py

package info (click to toggle)
apptainer 1.4.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,748 kB
  • sloc: sh: 3,321; ansic: 1,706; awk: 414; python: 103; makefile: 54
file content (153 lines) | stat: -rwxr-xr-x 4,739 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python

'''
Copyright (c) Contributors to the Apptainer project, established as
  Apptainer a Series of LF Projects LLC.
  For website terms of use, trademark policy, privacy policy and other
  project policies see https://lfprojects.org/policies

Copyright (c) 2017-2018, Sylabs, Inc. All rights reserved.

Copyright (c) 2015-2017, Gregory M. Kurtzer. All rights reserved.
Copyright (c) 2017, Vanessa Sochat All rights reserved.

Copyright (c) 2016, The Regents of the University of California, through
Lawrence Berkeley National Laboratory (subject to receipt of any required
approvals from the U.S. Dept. of Energy).  All rights reserved.

This software is licensed under a customized 3-clause BSD license.  Please
consult LICENSE file distributed with the sources of this project regarding
your rights to use or distribute this software.

NOTICE.
This Software was developed under funding from the U.S. Department of
Energy and the U.S. Government consequently retains certain rights. As such,
the U.S. Government has been granted for itself and others acting on its
behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software
to reproduce, distribute copies to the public, prepare derivative works, and
perform publicly and display publicly, and to permit other to do so.
'''

import os
import re
import sys
sys.path.append('../libexec/python')  # noqa

from sutils import (
    get_fullpath,
    read_file,
    write_file
)

from message import bot
import optparse


def get_parser():

    description = "apptainer configuration parsing helper in python"
    parser = optparse.OptionParser(description=description)

    # Configuration defaults header
    help = "configuration defaults header file (../src/lib/config_defaults.h)"
    parser.add_option("--defaults",
                      dest='defaults',
                      help=help,
                      type=str)

    # input configuration file
    help = "the configuration input file path (apptainer.conf.in)"
    parser.add_option("--infile",
                      dest='infile',
                      help=help,
                      type=str)

    # Output configuration file
    help = "the configuration output file path (apptainer.conf)"
    parser.add_option("--outfile",
                      dest='outfile',
                      help=help,
                      type=str)

    return parser


def main():
    '''parse configuration options and produce
       configuration output file
    '''
    bot.info("\n*** STARTING PYTHON CONFIGURATION HELPER ****")
    parser = get_parser()

    try:
        (args, options) = parser.parse_args()
    except Exception:
        bot.error("Input args to %s improperly set, exiting."
                  % os.path.abspath(__file__))
        parser.print_help()
        sys.exit(1)

    # Check for required args
    [check_required(parser, arg) for arg in [args.defaults,
                                             args.infile,
                                             args.outfile]]

    # Run the configuration
    configure(args)


def check_required(parser, arg):
    '''check_required arg checks that an argument is defined.
    It is a workaround for missing required parameter of argparse
    :param parser: the parser
    :param arg: the argument
    '''
    if not arg:   # if filename is not given
        parser.error('Missing required argument.')
        parser.print_help()
        sys.exit(1)


def configure(args):

    # Get fullpath to each file, and concurrently check that exists
    defaultfile = get_fullpath(args.defaults)  # ../src/lib/config_defaults.h
    infile = get_fullpath(args.infile)         # apptainer.conf.in

    # Find define statements
    define_re = re.compile("#define ([A-Z_]+) (.*)")

    # Read in input and default files
    defaultfile = read_file(defaultfile)
    data = "".join(read_file(infile))

    # Lookup for values we want replaced
    lookup = {'0': 'no',
              '1': 'yes'}

    defaults = {}
    # Read in defaults to dictionary
    for line in defaultfile:
        match = define_re.match(line)
        if match:
            key, value = match.groups()

            # Maintain the original default set by user
            defaults[key] = value

            # Use parsed value for final config
            new_value = value.replace('"', '')
            if new_value in lookup:
                new_value = lookup[new_value]
            data = data.replace("@" + key + "@", new_value)

    # Write to output file
    outfile = "%s.tmp" % args.outfile
    write_file(outfile, data)
    os.rename(outfile, args.outfile)

    bot.info("*** FINISHED PYTHON CONFIGURATION HELPER ****\n")


if __name__ == '__main__':
    main()