1
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
2
|
|
|
# -*- coding: future_fstrings -*- |
3
|
|
|
|
4
|
|
|
import json |
5
|
|
|
import os |
6
|
|
|
import shutil |
7
|
|
|
import subprocess |
8
|
|
|
import sys |
9
|
|
|
|
10
|
|
|
from lighthouse_garden.utility import output |
11
|
|
|
from lighthouse_garden.lighthouse import utility |
12
|
|
|
|
13
|
|
|
config = { |
14
|
|
|
'verbose': False, |
15
|
|
|
'mute': False, |
16
|
|
|
'run': 1, |
17
|
|
|
'export': False, |
18
|
|
|
'export_path': None, |
19
|
|
|
'config_file_path': None, |
20
|
|
|
'data_dir': 'd/', |
21
|
|
|
'keep_history': 0, |
22
|
|
|
'title': 'Lighthouse Garden', |
23
|
|
|
'description': 'Monitoring performance data by Google Lighthouse', |
24
|
|
|
'lighthouse': { |
25
|
|
|
'chrome_flags': '--no-sandbox --headless --disable-gpu --ignore-certificate-errors --disable-dev-shm-usage', |
|
|
|
|
26
|
|
|
'options': '--quiet --no-enable-error-reporting --preset=desktop --disable-storage-reset' |
27
|
|
|
} |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
|
31
|
|
|
def check_args(config_file=None, |
32
|
|
|
verbose=False): |
33
|
|
|
""" |
34
|
|
|
Check the input arguments |
35
|
|
|
:param config_file: |
36
|
|
|
:param verbose: |
37
|
|
|
:return: |
38
|
|
|
""" |
39
|
|
|
global config |
|
|
|
|
40
|
|
|
|
41
|
|
|
config['verbose'] = verbose |
42
|
|
|
|
43
|
|
|
if not config_file is None: |
44
|
|
|
config['config_file_path'] = config_file |
45
|
|
|
|
46
|
|
|
|
47
|
|
|
def check_config(additional_config={}): |
|
|
|
|
48
|
|
|
""" |
49
|
|
|
Checking configuration information by file or dictionary |
50
|
|
|
:param additional_config: Dictionary |
51
|
|
|
:return: |
52
|
|
|
""" |
53
|
|
|
global config |
|
|
|
|
54
|
|
|
|
55
|
|
|
if config['config_file_path'] is None and additional_config == {}: |
56
|
|
|
sys.exit(f'{output.Subject.ERROR} Configuration is missing') |
57
|
|
|
|
58
|
|
|
if additional_config: |
59
|
|
|
config.update(additional_config) |
60
|
|
|
|
61
|
|
|
_config_file_path = config['config_file_path'] |
62
|
|
|
if not _config_file_path is None: |
63
|
|
|
if os.path.isfile(_config_file_path): |
64
|
|
|
with open(_config_file_path, 'r') as read_file: |
65
|
|
|
config.update(json.load(read_file)) |
66
|
|
|
output.println( |
67
|
|
|
f'{output.Subject.INFO} Loading host configuration {output.CliFormat.BLACK}{_config_file_path}{output.CliFormat.ENDC}', verbose_only=True) |
|
|
|
|
68
|
|
|
else: |
69
|
|
|
sys.exit(f'{output.Subject.ERROR} Local configuration not found: {config["config_file_path"]}') |
|
|
|
|
70
|
|
|
|
71
|
|
|
|
72
|
|
|
def run_command(command, return_output=False, allow_fail=False): |
73
|
|
|
""" |
74
|
|
|
Run local command |
75
|
|
|
:param command: String Shell command |
76
|
|
|
:param return_output: Boolean Return shell command output |
77
|
|
|
:param allow_fail: Boolean |
78
|
|
|
:return: |
79
|
|
|
""" |
80
|
|
|
output.println( |
81
|
|
|
f'{output.Subject.DEBUG}{output.Subject.CMD} {output.CliFormat.BLACK}{command}{output.CliFormat.ENDC}', verbose_only=True) |
|
|
|
|
82
|
|
|
|
83
|
|
|
res = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) |
84
|
|
|
|
85
|
|
|
out, err = res.communicate() |
86
|
|
|
|
87
|
|
|
if res.wait() != 0 and err.decode() != '': |
88
|
|
|
_error_message = f'{output.Subject.ERROR} {err.decode()}' |
89
|
|
|
if allow_fail: |
|
|
|
|
90
|
|
|
output.println(_error_message) |
91
|
|
|
return False |
92
|
|
|
else: |
93
|
|
|
sys.exit(_error_message) |
94
|
|
|
|
95
|
|
|
if return_output: |
96
|
|
|
return out.decode() |
97
|
|
|
|
98
|
|
|
return True |
99
|
|
|
|
100
|
|
|
|
101
|
|
|
def check_lighthouse_version(): |
102
|
|
|
""" |
103
|
|
|
Check sshpass version |
104
|
|
|
:return: |
105
|
|
|
""" |
106
|
|
|
_version = run_command('lighthouse --version', return_output=True) |
107
|
|
|
|
108
|
|
|
if _version: |
109
|
|
|
output.println( |
110
|
|
|
f'{output.Subject.INFO} lighthouse version {_version}', |
111
|
|
|
verbose_only=True |
112
|
|
|
) |
113
|
|
|
config['lighthouse']['version'] = _version |
114
|
|
|
|
115
|
|
|
|
116
|
|
|
def check_path(path): |
117
|
|
|
""" |
118
|
|
|
Create a path on the system if not exists |
119
|
|
|
:param path: String Directory path |
120
|
|
|
:return: |
121
|
|
|
""" |
122
|
|
|
run_command( |
123
|
|
|
f'[ ! -d "{path}" ] && mkdir -p "{path}"' |
124
|
|
|
) |
125
|
|
|
|
126
|
|
|
|
127
|
|
|
def clear_data(): |
128
|
|
|
""" |
129
|
|
|
Clear the performance data and the lighthouse garden dashboard |
130
|
|
|
:return: |
131
|
|
|
""" |
132
|
|
|
output.println(f'{output.Subject.INFO} Clear data') |
133
|
|
|
_file_path = f'{config["export_path"]}index.html' |
134
|
|
|
_dir_path = utility.get_data_dir() |
135
|
|
|
|
136
|
|
|
if os.path.isfile(_file_path): |
137
|
|
|
os.remove(_file_path) |
138
|
|
|
|
139
|
|
|
shutil.rmtree(_dir_path) |
140
|
|
|
|