source: hwdetector/trunk/fuentes/valentin.install/usr/bin/valentin @ 6405

Last change on this file since 6405 was 6405, checked in by mabarracus, 23 months ago

Fixed utf-8 bug decoding files

  • Property svn:executable set to *
File size: 8.8 KB
Line 
1#!/usr/bin/env python
2import sys,os
3sys.path.insert(0,'/usr/lib/valentin/')
4import logging
5import hwdetector.utils.log as log
6import tarfile
7import datetime
8import tempfile
9import json
10import argparse
11import zlib
12import base64
13from ruleset import ruleset
14
15def run_in_debug():
16    gettrace=getattr(sys,'gettrace',None)
17    if gettrace is None:
18        return False
19    elif gettrace():
20        return True
21    else:
22        return None
23
24def indent_var(st=u'',var={},indent=0):
25    creturn=u'\n'
26    if indent==0:
27        creturn=creturn*2
28    indentation=u'\t'*indent
29    try:
30        if type(var) == type(dict()):
31            for x in sorted(var.keys()):
32                st += u'{}{}\n{}{}'.format(indentation,x,indent_var(var=var[x],indent=indent+1),creturn)
33        elif type(var) == type(list()):
34            if len(var) == 2 and var[0] == '__gz__':
35                content=zlib.decompress(base64.b64decode(var[1])).decode('utf-8')
36                replaced = content.replace(u'\n',indentation+u'\n'+indentation)
37                st += u'{}{}'.format(indentation,replaced)
38            else:
39                for x in sorted(var):
40                    st += u'{}\n'.format(indent_var(var=x,indent=indent+1))
41        elif type(var) == type(str()):
42            var = var.encode('utf-8')
43            replaced = var.replace(u'\n',indentation+u'\n'+indentation)
44            st += u'{}{}'.format(indentation,replaced)
45        elif type(var) == type(unicode()):
46            replaced = var.replace(u'\n',indentation+u'\n'+indentation)
47            st += u'{}{}'.format(indentation,replaced)
48        elif type(var) == type(bool()) or type(var) == type(int()) or type(var) == type(float()) or type(var) == type(tuple()) or var == None:
49            st += u'{}{}'.format(indentation,var)
50        else:
51            raise Exception('Unknown type var')
52        return st
53    except Exception as e:
54        return u''
55
56def make_file(capabilities,*args,**kwargs):
57    try:
58        txt = json.dumps(capabilities,indent=4,separators=(',',':'),sort_keys=True)
59        name = tempfile.mkstemp()[1]
60        with open(name,'w') as f:
61            f.write(txt.encode('utf-8'))
62        return name
63    except Exception as e:
64        return False
65
66def make_tar(file,*args,**kwargs):
67    try:
68        datestr='{:%Y%m%d%H%M}'.format(datetime.datetime.now())
69        if kwargs['fname']:
70            filename = kwargs['fname']
71        else:
72            filename = 'valentin-info-{}.tar.gz'.format(datestr)
73
74        if os.path.exists(file):
75            with tarfile.open(filename,'w:gz') as f:
76                f.add(file,arcname='debug-info-{}.txt'.format(datestr),recursive=False)
77                logger_message_file='/tmp/valentin-debug-log-messages.txt'
78                if os.path.exists(logger_message_file):
79                    f.add(logger_message_file,arcname=os.path.basename(logger_message_file))
80            return filename
81    except Exception as e:
82        return False
83
84def run_detection(*args,**kwargs):
85    log.debug("Importing hwdetector")
86    import hwdetector
87
88    log.debug("Instantiate HwDetector")
89    hwd=hwdetector.HwDetector()
90
91    #hwd.all_plugins_are_needed=True
92    if not run_in_debug():
93        log.info('USING MAX_RUNNING_TIME !!!')
94        hwd.MAX_RUNNING_TIME = 30
95
96    #hwd.fake_capabilities={'IAMGOD':'yes'}
97
98    log.debug("Calling run plugins")
99    #ret = hwd.run(needs=['ALL_TESTS'])
100    #ret = hwd.run(needs=['LLXSYSTEM_TEST','LLXNETWORK_TEST'])
101    ret = hwd.run()
102
103    # try:
104    #     file = make_file(hwd.capabilities,**kwargs)
105    #     if kwargs['to_stdout']:
106    #         print(file)
107    #     else:
108    #         fname=make_tar(file,**kwargs)
109    #         log.info("File {} created".format(fname))
110    # except Exception as e:
111    #     log.error("File creation unsuccessful "+str(e))
112
113    log.info("Total running time: {}".format(hwd.RUNNING_TIME))
114
115    return (ret,hwd.capabilities)
116
117def load_file(*args,**kwargs):
118    if kwargs.get('fname',None):
119        filename = kwargs['fname']
120    else:
121        return False
122    if os.path.exists(filename):
123        ftxt=None
124        if tarfile.is_tarfile(filename):
125            with tarfile.open(filename,'r:gz') as tar:
126                target_file=None
127
128                for tarinfo in tar.getmembers():
129                    if 'debug-info' in tarinfo.name.lower():
130                        target_file=tarinfo.name
131                        break
132                if target_file:
133                    ftxt = tar.extractfile(target_file).read()
134        else:
135            ftxt = None
136            with open(filename,'r') as f:
137                ftxt = f.read()
138        return ftxt
139    else:
140        return False
141
142def run_analysis(*args,**kwargs):
143
144    if kwargs.get('capabilities',None):
145        fileinfo = kwargs.get('capabilities')
146    if not kwargs.get('ruleset',None):
147        fileruleset='/usr/share/valentin/valentin.rules'
148        if not os.path.exists(fileruleset):
149            return False
150    else:
151        fileruleset=kwargs.get('ruleset')[0]
152
153    rs = ruleset()
154    try:
155        rs.load_ruleset(fileruleset=fileruleset,data=fileinfo)
156        rs.make_tree()
157        rs.make_suggestion()
158    except Exception as e:
159        log.error(e)
160
161    return True
162
163
164if __name__ == '__main__':
165    try:
166        parser = argparse.ArgumentParser(description='Simple system diagnostic tool')
167        dlevels = ['debug','info','warning','error']
168        parser.add_argument('-d','--debug-level',metavar='debug|info|warning|error',nargs='?',choices=dlevels,help='Set the debug level (default: warning)')
169        parser.add_argument('-c','--coloured',action='store_const',help='Colorize logger messages',const=True)
170
171        parser.add_argument('-f','--with-file',metavar='filename',nargs='?',help='Filename for results file (default valentin-info-(date).tar.gz')
172        parser.add_argument('-o','--to-stdout',action='store_const',help='Output results to stdout',const=True)
173        parser.add_argument('-w','--to-stdout-raw',action='store_const',help='Output results to stdout in json format',const=True)
174
175        parser.add_argument('-a','--analyze-file',metavar='filename',nargs=1,help='Filename to analyze')
176        parser.add_argument('-x','--run-detection',action='store_const',help='Run detection',const=True)
177
178        parser.add_argument('-s','--suggest',action='store_const',help='Suggest actions to repair system',const=True)
179        parser.add_argument('-r','--ruleset',metavar='filename',nargs=1,help='Load ruleset when suggest user actions')
180        args = parser.parse_args()
181
182        if not args.debug_level:
183            #log.set_level(logging.WARNING)
184            log.disable()
185        else:
186            levels={'debug':logging.DEBUG,'info':logging.INFO,'warning':logging.WARNING,'error':logging.ERROR}
187            log.set_level(levels[args.debug_level.lower()])
188
189        if args.coloured:
190            log.set_color(True)
191
192        kw=vars(args)
193
194        fname=None
195        if args.with_file:
196            fname=args.with_file
197            if '.' not in fname:
198                fname = fname + '.tar.gz'
199            kw.update({'fname':fname})
200
201        if args.analyze_file:
202            fname=args.analyze_file[0]
203            kw.update({'fname':fname})
204            capabilities=load_file(**kw)
205            if capabilities:
206                capabilities = json.loads(capabilities)
207                ret = True
208                log.info("File {} loaded".format(fname))
209                kw.update({'capabilities':capabilities})
210            else:
211                log.error("File {} can't be loaded".format(fname))
212                ret = False
213        else:
214            if args.run_detection:
215                ret,capabilities=run_detection(**kw)
216                log.info('Detection done!')
217                if args.with_file:
218                    try:
219                        file = make_file(capabilities,**kw)
220                        fname = make_tar(file,**kw)
221                        log.info("File {} created".format(fname))
222                    except Exception as e:
223                        log.error("File creation unsuccessful "+str(e))
224
225                kw.update({'capabilities':capabilities})
226            else:
227                sys.stderr.write('Missing detection option\n')
228                ret = False
229
230        if ret:
231            if args.to_stdout or args.to_stdout_raw:
232                if args.to_stdout:
233                    pr=indent_var(var=capabilities)
234                else:
235                    pr=json.dumps(capabilities,indent=4,separators=(',',':'),sort_keys=True)
236                sys.stdout.write(pr.encode('utf-8'))
237                sys.stderr.write('\n')
238
239            if args.suggest:
240                ret=run_analysis(**kw)
241
242
243        if ret:
244            log.info("Exit code = 0")
245            sys.exit(0)
246        else:
247            log.info("Exit code = 1")
248            sys.exit(1)
249
250    except Exception as e:
251        log.error("Exception occurred: {}".format(e))
252        log.error("Exit code = 1")
253        sys.exit(1)
254
Note: See TracBrowser for help on using the repository browser.