blob: e1030f9106ea1a2e262d5470a46317dfe97eed5a [file] [log] [blame]
Vasyl Saienko71547e62017-07-14 09:27:04 +03001#!/usr/bin/python
2
3from __future__ import print_function
4
5import argparse
6import os
7import sys
8import yaml
9
10def _merge_items(a, b, path=None):
11 """Merge b into a"""
12 if path is None: path = []
13 for key in b:
14 if key in a:
15 if isinstance(a[key], dict) and isinstance(b[key], dict):
16 _merge_items(a[key], b[key], path + [str(key)])
17 elif a[key] == b[key]:
18 pass # same leaf value
19 else:
20 raise Exception('Conflict at %s' % '.'.join(path + [str(key)]))
21 else:
22 a[key] = b[key]
23 return a
24
25def repo_add(content, name, source, pin_priority=None):
26 """Adds repo dict to provided content"""
27 t = {}
28 r = {name: {'architectures': 'amd64',
29 'source': source}}
30 if pin_priority:
31 r[name]['pin'] = [{'package': '*',
32 'priority': pin_priority,
33 'pin': 'release o=Ubuntu'}]
34 t['parameters'] = {'linux': {'system': {'repo': r}}}
35 _merge_items(content, t)
36
37def main():
38 parser = argparse.ArgumentParser(description='Update reclass model for specific node')
39 parser.add_argument('--node',
40 type=str,
41 help='FQDN of the node to update.')
42 parser.add_argument('--node-path',
43 type=str,
44 default='/srv/salt/reclass/nodes/_generated',
45 help='Path to directory with the nodes.')
46 subparsers = parser.add_subparsers()
47
48
49 # create the parser for the "add" command
50 parser_add = subparsers.add_parser('repo_add', help='Add a new repo.')
51 parser_add.set_defaults(command='repo_add')
52 parser_add.add_argument('--repo-name',
53 type=str,
54 required=True,
55 help='The name of the repo to add.')
56 parser_add.add_argument('--source',
57 type=str,
58 required=True,
59 help='The source link of the repo. For example: '
60 'deb http://my.repo.com/xenial ocata main')
61 parser_add.add_argument('--priority',
62 type=int,
63 help='The pin priority of the repo.')
64 args = parser.parse_args()
65
66 if args.node:
67 node_files = ['%s/%s.yml' % (args.node_path, args.node)]
68 else:
69
70 node_files = ['%s/%s' % (args.node_path, f) for f in os.listdir(args.node_path) if f.endswith('.yml')]
71
72 # check we can read the file
73 for node_file in node_files:
74 node_name = os.path.basename(node_file)[:-4]
75 if not os.access(node_file, os.W_OK):
76 print("Can not write to nodes file %s" % node_file, file=sys.stderr)
77 sys.exit(1)
78
79 try:
80 content = {}
81 with open(node_file) as f:
82 content = yaml.load(f)
83
84 if args.command == 'repo_add':
85 print("Adding repo to the node: %s" % node_name)
86 repo_add(content, args.repo_name, args.source, args.priority)
87
88 with open(node_file, "w") as f:
89 yaml.dump(content, f, default_flow_style=False)
90 print("Node: %s has been updated successfully." % node_name)
91
92 except Exception as e:
93 print(e, file=sys.stderr)
94 sys.exit(1)
95
96if __name__ == '__main__':
97 main()