summaryrefslogtreecommitdiff
path: root/pxeboot.check
blob: d7eb9b5c64c8df01969d56c3516eab803084dd34 (plain)
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
#!/usr/bin/python

import itertools
import os
import sys
flatten = itertools.chain.from_iterable

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return flatten(itertools.combinations(s, r) for r in range(len(s)+1))

valid_option_sets = frozenset((
    ('spawn-novlan', frozenset(('PXEBOOT_DEPLOYER_INTERFACE',))),
    ('spawn-vlan', frozenset(('PXEBOOT_DEPLOYER_INTERFACE',  'PXEBOOT_VLAN'))),
    ('existing-dhcp', frozenset(('PXEBOOT_DEPLOYER_INTERFACE',
                                 'PXEBOOT_CONFIG_TFTP_ADDRESS'))),
    ('existing-server', frozenset(('PXEBOOT_CONFIG_TFTP_ADDRESS',
                                   'PXEBOOT_ROOTFS_RSYNC_ADDRESS'))),
))
valid_modes = frozenset(mode for (mode, opt_set in valid_option_sets))


def compute_matches(env):
    complete_matches = set()
    for mode, opt_set in valid_option_sets:
        if all(k in env for k in opt_set):
            complete_matches.add(opt_set)
    return complete_matches
complete_matches = compute_matches(os.environ)

def word_separate_options(options):
    assert options
    s = options.pop(-1)
    if options:
        s = '%s and %s' % (', '.join(options), s)
    return s


valid_options = frozenset(flatten(opt_set for (mode, opt_set)
                                  in valid_option_sets))
matched_options = frozenset(o for o in valid_options)
                            if o in os.environ)
if not complete_matches:
    addable_sets = frozenset(frozenset(os) - matched_options for os in
                             valid_options
                             if frozenset(os) - matched_options)
    print('Please provide %s' % ' or '.join(
            word_separate_options(list(opt_set))
            for opt_set in addable_sets if opt_set))
    sys.exit(1)
elif len(complete_matches) > 1:
    removable_sets = frozenset(matched_options - frozenset(os) for os in
                               powerset(matched_options)
                               if len(compute_matches(os)) == 1)
    print('Please unset %s' % ' or '.join(
            word_separate_options(list(opt_set))
            for opt_set in removable_sets if opt_set))
    sys.exit(1)

if 'PXEBOOT_MODE' in os.environ:
    mode = os.environ['PXEBOOT_MODE']
else:
    mode, = (mode for (mode, opt_set) in valid_option_sets
             if all(o in os.environ for o in opt_set))

if mode not in valid_modes:
    print('%s is not a valid PXEBOOT_MODE' % mode)
    sys.exit(1)