blob: d57aef53603109525fd888d2b9d3a9d2628fb0bc [file] [log] [blame]
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +03001
Dennis Dmitriev6bd44252017-06-22 17:33:40 +03002import copy
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +03003import hashlib
4import os
5import re
6import tarfile
7
8import urllib2
9import yaml
10
Dennis Dmitrievde847d92017-06-26 18:58:05 +030011from reclass_tools import helpers
12
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +030013
Dennis Dmitriev6bd44252017-06-22 17:33:40 +030014def walkfiles(topdir, verbose=False):
15 walker = os.walk(topdir)
16 opener = open
17 prefix = ''
18 isdir = os.path.isdir(topdir)
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +030019
20 if isdir:
21 for dirName, subdirList, fileList in walker:
22 for filename in fileList:
23 filepath = os.path.join(dirName,filename)
24 if verbose:
25 print (prefix + filepath)
26 with OpenFile(filepath, opener) as log:
27 yield (log)
28 else:
29 if verbose:
30 print (topdir)
31 with OpenFile(topdir, opener) as log:
32 yield (log)
33
34
35def yaml_read(yaml_file):
36 if os.path.isfile(yaml_file):
37 with open(yaml_file, 'r') as f:
38 return yaml.load(f)
39 else:
40 print("\'{}\' is not a file!".format(yaml_file))
41
42
43class OpenFile(object):
44
45 fname = None
46 opener = None
47 readlines = None
48 fobj = None
49
50 def __init__(self, fname, opener):
51 self.fname = fname
52 self.opener = opener
53
54 def get_parser(self):
55 parsers = {'/lastlog': self.fake_parser,
56 '/wtmp': self.fake_parser,
57 '/btmp': self.fake_parser,
58 '/atop.log': self.fake_parser,
59 '/atop_': self.fake_parser,
60 '/atop_current': self.fake_parser,
61 '/supervisord.log': self.docker_parser,
62 '.gz': self.gz_parser,
63 '.bz2': self.gz_parser,
64 }
65 for w in parsers.keys():
66 if w in self.fname:
67 self.readlines = parsers[w]
68 return
69 try:
70 self.fobj = self.opener(self.fname, 'r')
71 self.readlines = self.plaintext_parser
72 except IOError as e:
73 print("Error opening file {0}: {1}".format(self.fname, e))
74 if self.fobj:
75 self.fobj.close()
76 self.fobj = None
77 self.readlines = self.fake_parser
78
79 def plaintext_parser(self):
80 try:
81 for s in self.fobj.readlines():
82 yield s
83 except IOError as e:
84 print("Error reading file {0}: {1}".format(self.fname, e))
85
86 def fake_parser(self):
87 yield ''
88
89 def docker_parser(self):
90 yield ''
91
92 def gz_parser(self):
93 yield ''
94
95 def bz2_parser(self):
96 yield ''
97
98 def __enter__(self):
99 self.get_parser()
100 return self
101
102 def __exit__(self, x, y, z):
103 if self.fobj:
104 self.fobj.close()
105
106
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300107def get_all_reclass_params(paths, verbose=False):
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300108 """Return dict with all used values for each param"""
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300109 _params = dict()
110 for path in paths:
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300111 for log in walkfiles(path, verbose):
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300112 if log.fname.endswith('.yml'):
113 model = yaml_read(log.fname)
114 if model is not None:
115 # Collect all params from the models
Dennis Dmitrievde847d92017-06-26 18:58:05 +0300116 _param = helpers.get_nested_key(model, ['parameters', '_param'])
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300117 if _param:
118 for key, val in _param.items():
119 if key in _params:
Dennis Dmitrievefaa1352017-06-19 12:56:11 +0300120 # Keep list values sorted
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300121 _params[key].append(val)
Dennis Dmitrievefaa1352017-06-19 12:56:11 +0300122 _params[key] = sorted(_params[key])
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300123 else:
124 _params[key] = [val]
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300125 return _params
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300126
127
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300128def remove_reclass_parameter(paths, key,
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300129 verbose=False,
130 pretend=False):
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300131 """Removes specified key from parameters from all reclass models
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300132
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300133 :param key: string with point-separated nested objects, for
134 example: parameters.linux.network.interface
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300135 :rtype dict: { 'file path': {nested_key}, ...}
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300136 """
137 remove_key = key.split('.')
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300138 found_keys = {}
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300139
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300140 for path in paths:
141 for fyml in walkfiles(path, verbose=verbose):
142 if fyml.fname.endswith('.yml'):
143 model = yaml_read(fyml.fname)
144 if model is not None:
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300145
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300146 # Clear linux.network.interfaces
Dennis Dmitrievde847d92017-06-26 18:58:05 +0300147 nested_key = helpers.get_nested_key(model, remove_key)
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300148 if nested_key:
149 found_keys[fyml.fname] = copy.deepcopy(nested_key)
150 if pretend:
151 print("\nFound {0} in {1}".format('.'.join(remove_key),
152 fyml.fname))
153 print(yaml.dump(nested_key, default_flow_style=False))
154 else:
155 print("\nRemoving {0} from {1}".format('.'.join(remove_key),
156 fyml.fname))
157 print(yaml.dump(nested_key, default_flow_style=False))
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300158
Dennis Dmitrievde847d92017-06-26 18:58:05 +0300159 helpers.remove_nested_key(model, remove_key)
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300160
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300161 with open(fyml.fname, 'w') as f:
162 f.write(
163 yaml.dump(
164 model, default_flow_style=False
165 )
Dennis Dmitriev672bd442017-06-16 18:13:54 +0300166 )
Dennis Dmitriev6bd44252017-06-22 17:33:40 +0300167 return found_keys