Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Georgios Dagkakis
slapos
Commits
d6634962
Commit
d6634962
authored
9 years ago
by
Alain Takoudjou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup monitor2 stack
parent
b1dcbf77
Changes
33
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
397 additions
and
1257 deletions
+397
-1257
stack/monitor2/buildout.cfg
stack/monitor2/buildout.cfg
+94
-139
stack/monitor2/cgi-httpd.conf.in
stack/monitor2/cgi-httpd.conf.in
+0
-85
stack/monitor2/index.html
stack/monitor2/index.html
+0
-10
stack/monitor2/instance-monitor.cfg.jinja2.in
stack/monitor2/instance-monitor.cfg.jinja2.in
+24
-58
stack/monitor2/monitor-service-run.in
stack/monitor2/monitor-service-run.in
+4
-0
stack/monitor2/monitor.cfg.in
stack/monitor2/monitor.cfg.in
+0
-290
stack/monitor2/monitor.py.in
stack/monitor2/monitor.py.in
+0
-141
stack/monitor2/scripts/monitor-password-promise.py
stack/monitor2/scripts/monitor-password-promise.py
+2
-1
stack/monitor2/scripts/monitor.py
stack/monitor2/scripts/monitor.py
+203
-0
stack/monitor2/scripts/run-promise.py
stack/monitor2/scripts/run-promise.py
+1
-2
stack/monitor2/scripts/status2rss.py
stack/monitor2/scripts/status2rss.py
+0
-0
stack/monitor2/templates/monitor-httpd.conf.in
stack/monitor2/templates/monitor-httpd.conf.in
+20
-0
stack/monitor2/templates/monitor-service.cfg.in
stack/monitor2/templates/monitor-service.cfg.in
+0
-0
stack/monitor2/templates/monitor.conf.in
stack/monitor2/templates/monitor.conf.in
+0
-0
stack/monitor2/templates/wrapper.in
stack/monitor2/templates/wrapper.in
+0
-0
stack/monitor2/web/default-promise-interface.html
stack/monitor2/web/default-promise-interface.html
+0
-0
stack/monitor2/web/index.html
stack/monitor2/web/index.html
+22
-0
stack/monitor2/web/logout.html
stack/monitor2/web/logout.html
+0
-0
stack/monitor2/web/monitor-password-interface.html
stack/monitor2/web/monitor-password-interface.html
+0
-0
stack/monitor2/web/monitor.css
stack/monitor2/web/monitor.css
+7
-0
stack/monitor2/web/monitor.js
stack/monitor2/web/monitor.js
+20
-7
stack/monitor2/webfile-directory/ansible-report.cgi.in
stack/monitor2/webfile-directory/ansible-report.cgi.in
+0
-0
stack/monitor2/webfile-directory/index.cgi.in
stack/monitor2/webfile-directory/index.cgi.in
+0
-190
stack/monitor2/webfile-directory/index.html.jinja2
stack/monitor2/webfile-directory/index.html.jinja2
+0
-35
stack/monitor2/webfile-directory/monitor-password.cgi.in
stack/monitor2/webfile-directory/monitor-password.cgi.in
+0
-29
stack/monitor2/webfile-directory/settings.cgi.in
stack/monitor2/webfile-directory/settings.cgi.in
+0
-64
stack/monitor2/webfile-directory/static/monitor-register.js
stack/monitor2/webfile-directory/static/monitor-register.js
+0
-17
stack/monitor2/webfile-directory/static/pure-min.css
stack/monitor2/webfile-directory/static/pure-min.css
+0
-11
stack/monitor2/webfile-directory/static/script.js
stack/monitor2/webfile-directory/static/script.js
+0
-35
stack/monitor2/webfile-directory/static/style.css
stack/monitor2/webfile-directory/static/style.css
+0
-31
stack/monitor2/webfile-directory/static/welcome.html
stack/monitor2/webfile-directory/static/welcome.html
+0
-11
stack/monitor2/webfile-directory/status-history.cgi.in
stack/monitor2/webfile-directory/status-history.cgi.in
+0
-44
stack/monitor2/webfile-directory/status.cgi.in
stack/monitor2/webfile-directory/status.cgi.in
+0
-57
No files found.
stack/monitor2/buildout.cfg
View file @
d6634962
...
...
@@ -13,18 +13,9 @@ extends =
parts +=
slapos-cookbook
dcron
monitor-eggs
eggs
extra-eggs
monitor-conf
monitor-bin
monitor-web-index-html
monitor-web-monitor-css
monitor-web-monitor-js
monitor-web-monitor-logout-cgi
monitor-web-monitor-logout-page
monitor-template
rss-bin
monitor2-template
[monitor-download-base]
recipe = hexagonit.recipe.download
...
...
@@ -32,9 +23,19 @@ download-only = true
url = ${:_profile_base_location_}/${:filename}
mode = 0644
[monitor-eggs]
[monitor-web-base]
<= monitor-download-base
url = ${:_profile_base_location_}/web/${:filename}
destination = ${buildout:parts-directory}/monitor-web
on-update = true
[monitor-template-base]
<= monitor-download-base
url = ${:_profile_base_location_}/templates/${:filename}
[eggs]
recipe = zc.recipe.egg
eggs =
eggs
+
=
collective.recipe.template
cns.recipe.symlink
...
...
@@ -45,79 +46,83 @@ eggs =
PyRSS2Gen
Jinja2
[make-rss-script]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/make-rss.sh.in
md5sum = 98c8f6fd81e405b0ad10db07c3776321
output = ${buildout:directory}/template-make-rss.sh.in
mode = 0644
[monitor-conf]
<= monitor-download-base
filename = monitor.conf.in
md5sum = 2db5c08c7e8658981b4b1e3f27fd5967
[monitor-bin]
<= monitor-download-base
filename = monitor.py.in
md5sum = 2484cb185c391890a05db26c2163af8e
# Monitor html files
# XXX Can be removed from software release
[monitor-web-default-promise-interface]
<= monitor-
download
-base
<= monitor-
web
-base
filename = default-promise-interface.html
md5sum = eaedae330cd155f8b693b418286d0d98
[monitor-web-index-html]
<= monitor-
download
-base
<= monitor-
web
-base
filename = index.html
md5sum =
262db07691c145301252a49b6b51d11d
md5sum =
58fe6ada21d1b0b25a2a38374ec676d3
[monitor-web-monitor-css]
<= monitor-
download
-base
<= monitor-
web
-base
filename = monitor.css
md5sum =
a18ab932e5e2e656995f47c7d4a7853a
md5sum =
3cb91de30c729143af78461431fc6f8c
[monitor-web-monitor-js]
<= monitor-download-base
filename = monitor.js.in
md5sum = 3451788c49d3664cd9b72551fab34a9b
[monitor-web-monitor-logout-cgi]
recipe = slapos.recipe.template:jinja2
filename = monitor-logout.py.cgi
md5sum = 5b3c0aa559722a3bae5a692ea9a0a441
mode = 0755
template = ${:_profile_base_location_}/${:filename}
rendered = ${buildout:directory}/monitor-logout.cgi
context = key python_executable buildout:executable
<= monitor-web-base
filename = monitor.js
md5sum = 29ee4b9a99a7164581ccf5cbf75d33ba
[monitor-web-monitor-logout-page]
<= monitor-
download
-base
filename =
monitor-
logout.html
<= monitor-
web
-base
filename = logout.html
md5sum = b210c6842df541305d299081bc1bf81e
[monitor-
web-monitor-promise-runner-cgi
]
[monitor-
password-promise-interface
]
<= monitor-download-base
filename = monitor-run-promise.py.cgi
md5sum = 15625e5bf6c1b57b9199250951ffc16e
filename = monitor-password-interface.html
url = ${:_profile_base_location_}/web/${:filename}
md5sum = 04b664dfb47bfd3d01502768311aa239
# End Monitor web files
[monitor-template]
# Monitor templates files
[monitor-httpd-conf]
<= monitor-template-base
md5sum = 8a1aa7cba281877d6cf63cb8ade64b5e
filename = monitor-httpd.conf.in
[monitor-service-conf-template]
<= monitor-template-base
filename = monitor-service.cfg.in
md5sum = 5913d2a0096b50537f394a49b762b3e5
[template-wrapper]
<= monitor-template-base
filename = wrapper.in
md5sum = 8cde04bfd0c0e9bd56744b988275cfd8
[monitor-conf]
<= monitor-template-base
filename = monitor.conf.in
md5sum = 2db5c08c7e8658981b4b1e3f27fd5967
# End templates files
[monitor2-template]
recipe = slapos.recipe.template:jinja2
filename = template-monitor.cfg
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
rendered = ${buildout:directory}/template-monitor.cfg
md5sum =
6d5f1ceff198262319566ee25093c350
md5sum =
bf0578bb6863fea73c1c40bc009c7654
context =
key apache_location apache:location
key gzip_location gzip:location
raw monitor_bin ${monitor
-bin:location}/${monitor
-bin:filename}
raw monitor_bin ${monitor
2-bin:location}/${monitor2
-bin:filename}
raw monitor_conf_template ${monitor-conf:location}/${monitor-conf:filename}
raw monitor_password_promise_template ${monitor-password-promise:location}/${monitor-password-promise:filename}
raw monitor_password_cgi_template ${monitor-password-
cgi:location}/${monitor-password
-cgi:filename}
raw monitor_password_cgi_template ${monitor-password-
py-cgi:location}/${monitor-password-py
-cgi:filename}
raw monitor_password_promise_interface_template ${monitor-password-promise-interface:location}/${monitor-password-promise-interface:filename}
raw monitor_web_default_promise_interface ${monitor-web-default-promise-interface:location}/${monitor-web-default-promise-interface:filename}
raw monitor_web_index_html ${monitor-web-index-html:location}/${monitor-web-index-html:filename}
raw monitor_web_monitor_css ${monitor-web-monitor-css:location}/${monitor-web-monitor-css:filename}
raw monitor_web_directory ${monitor-web-index-html:location}
key monitor_web_monitor_logout_cgi monitor-web-monitor-logout-cgi:rendered
raw monitor_web_monitor_logout_page ${monitor-web-monitor-logout-page:location}/${monitor-web-monitor-logout-page:filename}
raw monitor_web_monitor_promise_runner_cgi ${monitor-web-monitor-promise-runner-cgi:location}/${monitor-web-monitor-promise-runner-cgi:filename}
...
...
@@ -128,113 +133,63 @@ context =
raw logrotate_executable_location ${logrotate:location}/usr/sbin/logrotate
raw monitor_httpd_template ${monitor-httpd-conf:location}/${monitor-httpd-conf:filename}
raw monitor_service_conf_template ${monitor-service-conf-template:location}/${monitor-service-conf-template:filename}
raw monitor_service_run ${monitor-service-template-run:location}/${monitor-service-template-run:filename}
raw openssl_executable_location ${openssl:location}/bin/openssl
raw python_executable ${buildout:executable}
raw promise_executor_py ${run-promise-py:location}/${run-promise-py:filename}
raw template_wrapper ${template-wrapper:output}
raw status2rss_executable_path ${status2rss-executable:location}/${status2rss-executable:filename}
[monitor
-httpd-conf
]
[monitor
2-bin
]
<= monitor-download-base
md5sum = 625d3d948c0af7b4848d7fad92bfb844
filename = monitor-httpd.conf.in
filename = monitor.py
md5sum = 7e1f2210a87b2212d11524e06985dd49
url = ${:_profile_base_location_}/scripts/${:filename}
[
monitor-service-conf-template
]
[
run-promise-py
]
<= monitor-download-base
filename = monitor-service.cfg.in
md5sum = 5913d2a0096b50537f394a49b762b3e5
filename = run-promise.py
md5sum = 8a46adcbc126ec9589d1810ba291d048
mode = 0755
url = ${:_profile_base_location_}/scripts/${:filename}
[monitor-
service-template-run
]
[monitor-
password-promise
]
<= monitor-download-base
md5sum = d5f29fa859a45696e1ff1bb174ab1111
filename = monitor-service-run.in
filename = monitor-password-promise.py
md5sum = f7e937d6619eb674f39f34718928d91d
url = ${:_profile_base_location_}/scripts/${:filename}
[
run-promise-py
]
[
status2rss-executable
]
<= monitor-download-base
filename = run-promise.py
md5sum = 6db26ce13becf8a190e34c14cb8b6f9f
filename = status2rss.py
md5sum = 65315ded80cd72f54f6e12d06ce813c4
url = ${:_profile_base_location_}/scripts/${:filename}
[monitor-httpd-template]
<= monitor-download-base
md5sum = 93e1dda50cb71bfe29966b2946c02dd1
filename = cgi-httpd.conf.in
[index]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/webfile-directory/${:filename}
download-only = true
md5sum = e759977b21c70213daa4c2701f2c2078
destination = ${buildout:parts-directory}/monitor-index
filename = index.cgi.in
mode = 0644
[index-template]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/webfile-directory/${:filename}
download-only = true
destination = ${buildout:parts-directory}/monitor-template-index
md5sum = 7400c8cfa16a15a0d41f512b8bbb1581
filename = index.html.jinja2
[make-rss-script]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/make-rss.sh.in
md5sum = 98c8f6fd81e405b0ad10db07c3776321
output = ${buildout:directory}/template-make-rss.sh.in
mode = 0644
[status-cgi]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/webfile-directory/${:filename}
download-only = true
md5sum = e43d79bec8824265e22df7960744113a
destination = ${buildout:parts-directory}/monitor-template-status-cgi
filename = status.cgi.in
mode = 0644
[status-history-cgi]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/webfile-directory/${:filename}
download-only = true
#md5sum = 4fb26753ee669b8ac90ffe33dbd12e8f
destination = ${buildout:parts-directory}/monitor-template-status-history-cgi
filename = status-history.cgi.in
mode = 0644
[
settings
-cgi]
recipe =
hexagonit.recipe.download
url = ${:_profile_base_location_}/webfile-directory/${:filename}
download-only = true
m
d5sum = b4cef123a3273e848e8fe496e22b20a8
destination = ${buildout:parts-directory}/monitor-template-settings-cgi
filename = settings.cgi.in
mode = 0644
[
monitor-web-monitor-logout
-cgi]
recipe =
slapos.recipe.template:jinja2
filename = monitor-logout.py.cgi
md5sum = 5b3c0aa559722a3bae5a692ea9a0a441
m
ode = 0755
template = ${:_profile_base_location_}/${:filename}
rendered = ${buildout:directory}/monitor-logout.cgi
context = key python_executable buildout:executable
[monitor-
password-promise
]
[monitor-
web-monitor-promise-runner-cgi
]
<= monitor-download-base
filename = monitor-
password-promise.py.in
md5sum =
0a9a42551ed6bdb973fd1f0dd1d4ec86
filename = monitor-
run-promise.py.cgi
md5sum =
15625e5bf6c1b57b9199250951ffc16e
[monitor-password-cgi]
[monitor-password-
py-
cgi]
<= monitor-download-base
md5sum = 04fc7e6d892d29a601cfd43d1700eeda
filename = monitor-password.py.cgi
[monitor-password-promise-interface]
<= monitor-download-base
filename = monitor-password-interface.html
md5sum = 04b664dfb47bfd3d01502768311aa239
[status2rss-executable]
<= monitor-download-base
filename = status2rss.py
md5sum = 65315ded80cd72f54f6e12d06ce813c4
[dcron-service]
recipe = slapos.recipe.template
url = ${template-dcron-service:output}
output = $${directory:services}/crond
mode = 0700
logfile = $${directory:log}/crond.log
[template-wrapper]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/wrapper.in
output = ${buildout:directory}/template-wrapper.cfg
mode = 0644
md5sum = 8cde04bfd0c0e9bd56744b988275cfd8
This diff is collapsed.
Click to expand it.
stack/monitor2/cgi-httpd.conf.in
deleted
100644 → 0
View file @
b1dcbf77
PidFile "{{ httpd_configuration.get('pid-file') }}"
StartServers 1
ServerLimit 1
ThreadLimit 4
ThreadsPerChild 4
ServerName example.com
ServerAdmin someone@email
<IfDefine !MonitorPort>
Listen [{{ httpd_configuration.get('listening-ip') }}]:{{ monitor_parameters.get('port') }}
Define MonitorPort
</IfDefine>
DocumentRoot "{{ directory.get('www') }}"
ErrorLog "{{ httpd_configuration.get('error-log') }}"
LoadModule unixd_module modules/mod_unixd.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule mime_module modules/mod_mime.so
LoadModule cgid_module modules/mod_cgid.so
LoadModule dir_module modules/mod_dir.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule alias_module modules/mod_alias.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
# SSL Configuration
<IfDefine !SSLConfigured>
Define SSLConfigured
SSLCertificateFile {{ httpd_configuration.get('certificate') }}
SSLCertificateKeyFile {{ httpd_configuration.get('key') }}
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLRandomSeed startup /dev/urandom 256
SSLRandomSeed connect builtin
SSLProtocol -ALL +SSLv3 +TLSv1
SSLHonorCipherOrder On
SSLCipherSuite RC4-SHA:HIGH:!ADH
</IfDefine>
SSLEngine On
ScriptSock {{ httpd_configuration.get('cgid-pid-file') }}
<Directory {{ directory.get('www') }}>
SSLVerifyDepth 1
SSLRequireSSL
SSLOptions +StrictRequire
# XXX: security????
Options +ExecCGI
AddHandler cgi-script .cgi
DirectoryIndex {{ monitor_parameters.get('index-filename') }}
</Directory>
Alias /private/ {{ directory.get('private-directory') }}/
<Directory {{ directory.get('private-directory') }}>
Order Deny,Allow
Deny from env=AUTHREQUIRED
<Files ".??*">
Order Allow,Deny
Deny from all
</Files>
AuthType Basic
AuthName "Private access"
AuthUserFile "{{ monitor_parameters.get('htaccess-file') }}"
Require valid-user
Options Indexes FollowSymLinks
Satisfy all
</Directory>
<Location /rewrite>
AuthType Basic
AuthName "Private access"
AuthUserFile "{{ monitor_parameters.get('htaccess-file') }}"
Require valid-user
</Location>
ProxyVia On
RewriteEngine On
{% for key, value in monitor_rewrite_rule.iteritems() %}
RewriteRule ^/rewrite/{{ key }}($|/.*) {{ value }}/$1 [P,L]
{% endfor %}
This diff is collapsed.
Click to expand it.
stack/monitor2/index.html
deleted
100644 → 0
View file @
b1dcbf77
<!DOCTYPE html>
<html>
<head>
<link
rel=
"stylesheet"
href=
"monitor.css"
/>
<script
src=
"monitor.js"
></script>
</head>
<body>
<noscript>
Please enable javascript on your browser to make this application to work.
</noscript>
</body>
</html>
This diff is collapsed.
Click to expand it.
stack/monitor2/instance-monitor.cfg.jinja2.in
View file @
d6634962
...
...
@@ -115,14 +115,18 @@ wrapper = ${directory:services}/monitor-httpd
[monitor-conf-parameters]
title = ${monitor-instance-parameter:monitor-title}
service-executable-dir = ${monitor-directory:run}
template-service-run = {{ monitor_service_run }}
public-folder = ${monitor-directory:public}
private-folder = ${monitor-directory:private}
web-folder = ${monitor-directory:web-dir}
monitor-hal-json = ${monitor-directory:web-dir}/monitor.haljson
service-pid-folder = ${monitor-directory:pids}
crond-folder = ${logrotate-directory:cron-entries}
wraper-folder = ${monitor-directory:promise-wrapper}
promise-runner = {{ promise_executor_py }}
promise-folder-list =
${directory:promises}
${directory:monitor-promise}
public-path-list =
${directory:log}
private-path-list =
...
...
@@ -136,6 +140,19 @@ rendered = ${directory:etc}/${:filename}
filename = monitor.conf
context = section parameter_dict monitor-conf-parameters
[python-symlink]
recipe = plone.recipe.command
target = ${directory:bin}
command = ln -sf {{ python_executable }} ${:target}/python
update-command = ${:command}
[start-monitor]
recipe = slapos.cookbook:wrapper
command-line = {{ python_executable }} {{ monitor_bin }} --config_file ${monitor-conf:rendered}
wrapper-path = ${directory:scripts}/bootstrap-monitor
environment =
PATH=${python-symlink:target}:/usr/local/bin:/usr/bin:/bin
[httpd-monitor-htpasswd]
recipe = plone.recipe.command
stop-on-error = true
...
...
@@ -195,30 +212,11 @@ name = monitor-status2rss
frequency = * * * * *
command = ${monitor-status2rss-wrapper:wrapper-path}
[monitor-web-default-promise-interface]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_default_promise_interface }}
rendered = ${monitor-directory:web-dir}/default-promise-interface.html
context =
[monitor-web-index-html]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_index_html }}
rendered = ${monitor-directory:web-dir}/index.html
context =
[monitor-web-monitor-css]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_css }}
rendered = ${monitor-directory:web-dir}/monitor.css
context =
[monitor-web-directory]
recipe = plone.recipe.command
command = cp -f {{ monitor_web_directory }}/* ${monitor-directory:web-dir}
update-command = ${:command}
[monitor-web-monitor-js]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_js }}
rendered = ${monitor-directory:web-dir}/monitor.js
context =
key monitor_title monitor-instance-parameter:monitor-title
[monitor-web-monitor-logout-cgi]
recipe = slapos.recipe.template:jinja2
...
...
@@ -227,12 +225,6 @@ rendered = ${monitor-directory:cgi-bin}/monitor-logout.cgi
mode = 0755
context =
[monitor-web-monitor-logout-page]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_logout_page }}
rendered = ${monitor-directory:web-dir}/logout
context =
[monitor-web-monitor-promise-runner-cgi]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_promise_runner_cgi }}
...
...
@@ -242,28 +234,6 @@ context =
raw python_executable {{ python_executable }}
key promise_wrapper_folder monitor-directory:promise-wrapper
[start-monitor]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_bin }}
rendered = ${directory:scripts}/bootstrap-monitor
context =
raw python_executable {{ python_executable }}
key public_folder monitor-directory:public
key private_folder monitor-directory:private
key monitor_configuration_path monitor-conf:rendered
key promise_runner_path monitor-run-promise:rendered
key promise_folder directory:promises
key monitor_promise_folder directory:monitor-promise
key promise_wrapper_folder monitor-directory:promise-wrapper
[monitor-run-promise]
recipe = slapos.recipe.template:jinja2
template = {{ promise_executor_py }}
rendered = ${directory:bin}/monitor-run-promise
mode = 700
context =
raw python_executable {{ python_executable }}
[monitor-httpd-promise]
recipe = slapos.cookbook:check_url_available
path = ${directory:promises}/${:filename}
...
...
@@ -337,12 +307,8 @@ monitor-title = Monitoring interface
[buildout]
parts =
monitor-web-default-promise-interface
monitor-web-index-html
monitor-web-monitor-css
monitor-web-monitor-js
monitor-web-directory
monitor-web-monitor-logout-cgi
monitor-web-monitor-logout-page
monitor-web-monitor-promise-runner-cgi
cron-entry-logrotate
certificate-authority
...
...
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor-service-run.in
View file @
d6634962
...
...
@@ -34,4 +34,8 @@ def main():
pidfile
.
write
(
str
(
process
.
pid
))
if
__name__
==
"__main__"
:
if
len
(
sys
.
argv
)
==
1
:
print
"Use: %s Monitor_Config_File"
sys
.
exit
(
1
)
sys
.
exit
(
main
())
\ No newline at end of file
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor.cfg.in
deleted
100644 → 0
View file @
b1dcbf77
[slap-parameters]
recipe = slapos.cookbook:slapconfiguration
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
[monitor-parameters]
json-filename = monitor.json
json-path = $${monitor-directory:monitor-result}/$${:json-filename}
rss-filename = rssfeed.html
rss-path = $${monitor-directory:public-cgi}/$${:rss-filename}
executable = $${monitor-directory:bin}/monitor.py
port = 9685
htaccess-file = $${monitor-directory:etc}/.htaccess-monitor
url = https://[$${slap-parameters:ipv6-random}]:$${:port}
index-filename = index.cgi
index-path = $${monitor-directory:www}/$${:index-filename}
db-path = $${monitor-directory:etc}/monitor.db
monitor-password-path = $${monitor-directory:etc}/.monitor.shadow
[monitor-directory]
recipe = slapos.cookbook:mkdirectory
# Standard directory needed by monitoring stack
home = $${buildout:directory}
etc = $${:home}/etc
bin = $${:home}/bin
srv = $${:home}/srv
var = $${:home}/var
log = $${:var}/log
run = $${:var}/run
service = $${:etc}/service/
etc-run = $${:etc}/run/
tmp = $${:home}/tmp
promise = $${:etc}/promise
cron-entries = $${:etc}/cron.d
crontabs = $${:etc}/crontabs
cronstamps = $${:etc}/cronstamps
ca-dir = $${:srv}/ssl
www = $${:var}/www
cgi-bin = $${:var}/cgi-bin
monitoring-cgi = $${:cgi-bin}/monitoring
knowledge0-cgi = $${:cgi-bin}/zero-knowledge
public-cgi = $${:cgi-bin}/monitor-public
monitor-custom-scripts = $${:etc}/monitor
monitor-result = $${:var}/monitor
private-directory = $${:srv}/monitor-private
[public-symlink]
recipe = cns.recipe.symlink
symlink = $${monitor-directory:public-cgi} = $${monitor-directory:www}/monitor-public
autocreate = true
[cron]
recipe = slapos.cookbook:cron
dcrond-binary = ${dcron:location}/sbin/crond
cron-entries = $${monitor-directory:cron-entries}
crontabs = $${monitor-directory:crontabs}
cronstamps = $${monitor-directory:cronstamps}
catcher = $${cron-simplelogger:wrapper}
binary = $${monitor-directory:service}/crond
# Add log to cron
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = $${monitor-directory:bin}/cron_simplelogger
log = $${monitor-directory:log}/cron.log
[cron-entry-monitor]
<= cron
recipe = slapos.cookbook:cron.d
name = launch-monitor
frequency = */5 * * * *
command = $${deploy-monitor-script:rendered} -a
[cron-entry-rss]
<= cron
recipe = slapos.cookbook:cron.d
name = build-rss
frequency = */5 * * * *
command = $${make-rss:rendered}
[setup-static-files]
recipe = plone.recipe.command
command = ln -s ${download-monitor-jquery:destination} $${monitor-directory:www}/static
update-command = $${:command}
[deploy-index]
recipe = slapos.recipe.template:jinja2
template = ${index:location}/${index:filename}
rendered = $${monitor-parameters:index-path}
update-apache-access = ${apache:location}/bin/htpasswd -cb $${monitor-parameters:htaccess-file} admin
mode = 0744
context =
key cgi_directory monitor-directory:cgi-bin
raw index_template $${deploy-index-template:location}/$${deploy-index-template:filename}
key monitor_password_path monitor-parameters:monitor-password-path
key monitor_password_script_path deploy-monitor-password-cgi:rendered
key apache_update_command :update-apache-access
raw extra_eggs_interpreter ${buildout:directory}/bin/${extra-eggs:interpreter}
raw default_page /static/welcome.html
section rewrite_element monitor-rewrite-rule
[deploy-index-template]
recipe = hexagonit.recipe.download
url = ${index-template:location}/$${:filename}
destination = $${monitor-directory:www}
filename = ${index-template:filename}
download-only = true
mode = 0644
[deploy-status-cgi]
recipe = slapos.recipe.template:jinja2
template = ${status-cgi:location}/${status-cgi:filename}
rendered = $${monitor-directory:monitoring-cgi}/$${:filename}
filename = status.cgi
mode = 0744
context =
key json_file monitor-parameters:json-path
key monitor_bin monitor-parameters:executable
key pwd monitor-directory:monitoring-cgi
key this_file :filename
raw python_executable ${buildout:executable}
[deploy-status-history-cgi]
recipe = slapos.recipe.template:jinja2
template = ${status-history-cgi:location}/${status-history-cgi:filename}
rendered = $${monitor-directory:monitoring-cgi}/$${:filename}
filename = status-history.cgi
mode = 0744
context =
key monitor_db_path monitor-parameters:db-path
key status_history_length zero-parameters:status-history-length
raw python_executable ${buildout:executable}
[deploy-settings-cgi]
recipe = slapos.recipe.template:jinja2
template = ${settings-cgi:location}/${settings-cgi:filename}
rendered = $${monitor-directory:knowledge0-cgi}/$${:filename}
filename = settings.cgi
mode = 0744
context =
raw config_cfg $${buildout:directory}/knowledge0.cfg
raw timestamp $${buildout:directory}/.timestamp
raw python_executable ${buildout:executable}
key pwd monitor-directory:knowledge0-cgi
key this_file :filename
[deploy-monitor-password-cgi]
recipe = slapos.recipe.template:jinja2
template = ${monitor-password-cgi:location}/${monitor-password-cgi:filename}
rendered = $${monitor-directory:knowledge0-cgi}/$${:filename}
filename = monitor-password.cgi
mode = 0744
context =
raw python_executable ${buildout:executable}
key pwd monitor-directory:knowledge0-cgi
key this_file :filename
[deploy-monitor-script]
recipe = slapos.recipe.template:jinja2
template = ${monitor-bin:location}/${monitor-bin:filename}
rendered = $${monitor-parameters:executable}
mode = 0744
context =
section directory monitor-directory
section monitor_parameter monitor-parameters
key monitoring_file_json monitor-parameters:json-path
raw python_executable ${buildout:executable}
[make-rss]
recipe = slapos.recipe.template:jinja2
template = ${make-rss-script:output}
rendered = $${monitor-directory:bin}/make-rss.sh
mode = 0744
context =
section directory monitor-directory
section monitor_parameters monitor-parameters
[monitor-directory-access]
recipe = plone.recipe.command
command = ln -s $${:source} $${monitor-directory:private-directory}
source =
[monitor-instance-log-access]
recipe = plone.recipe.command
command = if [ -d $${:source} ]; then ln -s $${:source} $${monitor-directory:private-directory}/instance-logs; fi
update-command = if [ -d $${:source} ]; then ln -s $${:source} $${monitor-directory:private-directory}/instance-logs; fi
source = $${monitor-directory:home}/.slapgrid/log/
location = $${:source}
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = $${monitor-directory:ca-dir}/requests/
private = $${monitor-directory:ca-dir}/private/
certs = $${monitor-directory:ca-dir}/certs/
newcerts = $${monitor-directory:ca-dir}/newcerts/
crl = $${monitor-directory:ca-dir}/crl/
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${monitor-directory:ca-dir}
requests-directory = $${cadirectory:requests}
wrapper = $${monitor-directory:service}/certificate_authority
ca-private = $${cadirectory:private}
ca-certs = $${cadirectory:certs}
ca-newcerts = $${cadirectory:newcerts}
ca-crl = $${cadirectory:crl}
[ca-httpd]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = $${cadirectory:certs}/httpd.key
cert-file = $${cadirectory:certs}/httpd.crt
executable = $${monitor-directory:bin}/cgi-httpd
wrapper = $${monitor-directory:service}/cgi-httpd
# Put domain name
name = example.com
###########
# Deploy a webserver running cgi scripts for monitoring
###########
[public]
recipe = slapos.cookbook:zero-knowledge.write
filename = knowledge0.cfg
status-history-length = 5
[zero-parameters]
recipe = slapos.cookbook:zero-knowledge.read
filename = $${public:filename}
[monitor-rewrite-rule]
# XXX could it be something lighter?
[monitor-httpd-configuration]
pid-file = $${monitor-directory:run}/cgi-httpd.pid
cgid-pid-file = $${monitor-directory:run}/cgi-httpd-cgid.pid
error-log = $${monitor-directory:log}/cgi-httpd-error-log
listening-ip = $${slap-parameters:ipv6-random}
certificate = $${ca-httpd:cert-file}
key = $${ca-httpd:key-file}
[monitor-httpd-configuration-file]
recipe = slapos.recipe.template:jinja2
template = ${monitor-httpd-template:destination}/${monitor-httpd-template:filename}
rendered = $${monitor-directory:etc}/cgi-httpd.conf
mode = 0744
context =
section directory monitor-directory
section monitor_parameters monitor-parameters
section httpd_configuration monitor-httpd-configuration
section monitor_rewrite_rule monitor-rewrite-rule
[cgi-httpd-wrapper]
recipe = slapos.cookbook:wrapper
apache-executable = ${apache:location}/bin/httpd
command-line = $${:apache-executable} -f $${monitor-httpd-configuration-file:rendered} -DFOREGROUND
wrapper-path = $${ca-httpd:executable}
wait-for-files =
$${cadirectory:certs}/httpd.key
$${cadirectory:certs}/httpd.crt
[cgi-httpd-graceful-wrapper]
recipe = slapos.recipe.template:jinja2
template = ${template-wrapper:output}
rendered = $${monitor-directory:etc-run}/cgi-httpd-graceful
mode = 0700
context =
key content :command
command = kill -USR1 $(cat $${monitor-httpd-configuration:pid-file})
[monitor-promise]
recipe = slapos.cookbook:check_url_available
path = $${monitor-directory:promise}/monitor
url = $${monitor-parameters:url}/$${monitor-parameters:index-filename}
check-secure = 1
dash_path = ${dash:location}/bin/dash
curl_path = ${curl:location}/bin/curl
[publish-connection-informations]
recipe = slapos.cookbook:publish
monitor_url = $${monitor-parameters:url}
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor.py.in
deleted
100644 → 0
View file @
b1dcbf77
#!{{ python_executable }}
# Put this file in the software release
promise_runner_path = "{{ promise_runner_path }}"
public_folder = "{{ public_folder }}"
private_folder = "{{ private_folder }}"
monitor_configuration_path = "{{ monitor_configuration_path }}"
promise_folder = "{{ promise_folder }}"
monitor_promise_folder = "{{ monitor_promise_folder }}"
promise_wrapper_folder = "{{ promise_wrapper_folder }}"
import sys
import os
import stat
import subprocess
import threading
import json
import ConfigParser
import traceback
def main():
# initialisation
config = loadConfig([monitor_configuration_path])
# get promises in monitor_promise_folder
promise_dict = {}
fillPromiseDictFromFolder(promise_dict, monitor_promise_folder)
# get promises in promise_folder
fillPromiseDictFromFolder(promise_dict, promise_folder)
# get promises configurations
for filename in os.listdir(monitor_promise_folder):
path = os.path.join(monitor_promise_folder, filename)
if os.path.isfile(path) and filename[-4:] == ".cfg":
promise_name = filename[:-4]
if promise_name in promise_dict:
loadConfig([path], promise_dict[promise_name]["configuration"])
promise_items = promise_dict.items()
# create symlinks from service configurations
for service_name, promise in promise_items:
service_config = promise["configuration"]
createSymlinksFromConfig((config, "monitor", "public-folder"), (service_config, "service", "public-path-list"), service_name)
createSymlinksFromConfig((config, "monitor", "private-folder"), (service_config, "service", "private-path-list"), service_name)
# create symlinks from monitor.conf
createSymlinksFromConfig((config, "monitor", "public-folder"), (config, "monitor", "public-path-list"))
createSymlinksFromConfig((config, "monitor", "private-folder"), (config, "monitor", "private-path-list"))
# generate monitor.json
monitor_dict = {}
tmp = softConfigGet(config, "monitor", "title")
if tmp:
monitor_dict["title"] = tmp
tmp = softConfigGet(config, "monitor", "monitor-url-list")
if tmp:
monitor_dict["_links"] = {"related_monitor": [{"href": url} for url in tmp.split()]}
if promise_items:
service_list = []
monitor_dict["_embedded"] = {"service": service_list}
for service_name, promise in promise_items:
service_config = promise["configuration"]
service_dict = {}
service_list.append(service_dict)
service_dict["id"] = service_name
service_dict["_links"] = {"status": {"href": "/public/%s.status.json" % service_name}} # hardcoded
tmp = softConfigGet(service_config, "service", "title")
if tmp:
service_dict["title"] = tmp
interface_path = os.path.join(private_folder, service_name, "interface/index.html") # hardcoded
if os.path.isfile(interface_path):
service_dict["_links"]["interface"] = {"href": "/private/%s/interface/" % service_name} # hardcoded
else:
service_dict["_links"]["interface"] = {"href": "/default-promise-interface.html?service_name=%s" % service_name} # XXX hardcoded
with open(config.get("monitor", "monitor-hal-json"), "w") as fp:
json.dump(monitor_dict, fp)
# put promises to a cron file
# XXX only if at least one configuration file is modified, then write in the cron
service_pid_folder = config.get("monitor", "service-pid-folder")
crond_folder = config.get("monitor", "crond-folder")
cron_line_list = []
for service_name, promise in promise_items:
service_status_path = "%s/%s.status.json" % (public_folder, service_name) # hardcoded
mkdirAll(os.path.dirname(service_status_path))
command = ("%s %s %s " % (
promise_runner_path,
os.path.join(service_pid_folder, "%s.pid" % service_name),
service_status_path,
)) + promise["path"]
cron_line_list.append("%s %s" % (
softConfigGet(service_config, "service", "frequency") or "* * * * *",
command.replace("%", "\\%"),
))
wrapper_path = os.path.join(promise_wrapper_folder, service_name)
with open(wrapper_path, "w") as fp:
fp.write("#!/bin/sh\n%s" % command) # XXX hardcoded, use dash, sh or bash binary!
os.chmod(wrapper_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IROTH )
with open(crond_folder + "/monitor-promises", "w") as fp:
fp.write("\n".join(cron_line_list))
return 0
def loadConfig(pathes, config=None):
if config is None:
config = ConfigParser.ConfigParser()
try:
config.read(pathes)
except ConfigParser.MissingSectionHeaderError:
traceback.print_exc()
return config
def fillPromiseDictFromFolder(promise_dict, folder):
for filename in os.listdir(folder):
path = os.path.join(folder, filename)
if os.path.isfile(path) and os.access(path, os.X_OK):
promise_dict[filename] = {"path": path, "configuration": ConfigParser.ConfigParser()}
def softConfigGet(config, *args, **kwargs):
try:
return config.get(*args, **kwargs)
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
return None
def createSymlinksFromConfig(destination_folder_config_tuple, source_list_config_tuple, service_name=""):
destination_folder = softConfigGet(*destination_folder_config_tuple)
if destination_folder:
source_path_str = softConfigGet(*source_list_config_tuple)
if source_path_str:
for path in source_path_str.split():
dirname = os.path.join(destination_folder, service_name)
try:
mkdirAll(dirname) # could also raise OSError
os.symlink(path, os.path.join(dirname, os.path.basename(path)))
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
def mkdirAll(path):
try:
os.makedirs(path)
except OSError, e:
if e.errno == os.errno.EEXIST and os.path.isdir(path):
pass
else: raise
if __name__ == "__main__":
sys.exit(main())
This diff is collapsed.
Click to expand it.
stack/monitor2/
monitor-password-promise.py.in
→
stack/monitor2/
scripts/monitor-password-promise.py
View file @
d6634962
#!{{ python_executable }}
#!/usr/bin/env python
password_changed_once_path
=
"{{ password_changed_once_path }}"
import
os
...
...
This diff is collapsed.
Click to expand it.
stack/monitor2/scripts/monitor.py
0 → 100644
View file @
d6634962
#!/usr/bin/env python
import
sys
import
os
import
stat
import
subprocess
import
threading
import
json
import
ConfigParser
import
traceback
import
argparse
def
parseArguments
():
"""
Parse arguments for monitor instance.
"""
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
'--config_file'
,
default
=
'monitor.cfg'
,
help
=
'Monitor Configuration file'
)
parser
.
add_argument
(
'--promise-folder'
,
action
=
'append'
,
dest
=
'promise_folder_list'
,
default
=
[],
help
=
'The path to get promise executable files'
)
parser
.
add_argument
(
'--public-folder'
,
action
=
'append'
,
dest
=
'public_folder'
,
help
=
'The path of public folder. All files in this folders will have public acess'
)
parser
.
add_argument
(
'--private-folder'
,
action
=
'append'
,
dest
=
'private_folder'
,
help
=
'The path of private folder. All files in this folders will be accessible with password'
)
parser
.
add_argument
(
'--promise-runner'
,
help
=
'The path of promise runner, use to run promise files'
)
parser
.
add_argument
(
'--wrapper-path'
,
help
=
'Path of monitor generated promise scripts files.'
)
return
parser
.
parse_args
()
def
mkdirAll
(
path
):
try
:
os
.
makedirs
(
path
)
except
OSError
,
e
:
if
e
.
errno
==
os
.
errno
.
EEXIST
and
os
.
path
.
isdir
(
path
):
pass
else
:
raise
def
softConfigGet
(
config
,
*
args
,
**
kwargs
):
try
:
return
config
.
get
(
*
args
,
**
kwargs
)
except
(
ConfigParser
.
NoOptionError
,
ConfigParser
.
NoSectionError
):
return
None
class
Monitoring
(
object
):
def
__init__
(
self
,
configuration_file
):
config
=
self
.
loadConfig
([
configuration_file
])
# Set Monitor variables
self
.
monitor_hal_json
=
config
.
get
(
"monitor"
,
"monitor-hal-json"
)
self
.
title
=
config
.
get
(
"monitor"
,
"title"
)
self
.
service_pid_folder
=
config
.
get
(
"monitor"
,
"service-pid-folder"
)
self
.
crond_folder
=
config
.
get
(
"monitor"
,
"crond-folder"
)
self
.
wraper_folder
=
config
.
get
(
"monitor"
,
"wraper-folder"
)
self
.
promise_runner
=
config
.
get
(
"monitor"
,
"promise-runner"
)
self
.
promise_folder_list
=
config
.
get
(
"monitor"
,
"promise-folder-list"
).
split
()
self
.
public_folder
=
config
.
get
(
"monitor"
,
"public-folder"
)
self
.
private_folder
=
config
.
get
(
"monitor"
,
"private-folder"
)
self
.
public_path_list
=
config
.
get
(
"monitor"
,
"public-path-list"
).
split
()
self
.
private_path_list
=
config
.
get
(
"monitor"
,
"private-path-list"
).
split
()
self
.
monitor_url_list
=
config
.
get
(
"monitor"
,
"monitor-url-list"
).
split
()
self
.
promise_dict
=
{}
for
promise_folder
in
self
.
promise_folder_list
:
self
.
setupPromiseDictFromFolder
(
promise_folder
)
def
loadConfig
(
self
,
pathes
,
config
=
None
):
if
config
is
None
:
config
=
ConfigParser
.
ConfigParser
()
try
:
config
.
read
(
pathes
)
except
ConfigParser
.
MissingSectionHeaderError
:
traceback
.
print_exc
()
return
config
def
setupPromiseDictFromFolder
(
self
,
folder
):
for
filename
in
os
.
listdir
(
folder
):
path
=
os
.
path
.
join
(
folder
,
filename
)
if
os
.
path
.
isfile
(
path
)
and
os
.
access
(
path
,
os
.
X_OK
):
self
.
promise_dict
[
filename
]
=
{
"path"
:
path
,
"configuration"
:
ConfigParser
.
ConfigParser
()}
# get promises configurations
#for filename in os.listdir(monitor_promise_folder):
# path = os.path.join(monitor_promise_folder, filename)
# if os.path.isfile(path) and filename[-4:] == ".cfg":
# promise_name = filename[:-4]
# if promise_name in promise_dict:
# loadConfig([path], promise_dict[promise_name]["configuration"])
def
createSymlinksFromConfig
(
self
,
destination_folder
,
source_path_list
,
service_name
=
""
):
if
destination_folder
:
if
source_path_list
:
for
path
in
source_path_list
:
dirname
=
os
.
path
.
join
(
destination_folder
,
service_name
)
try
:
mkdirAll
(
dirname
)
# could also raise OSError
os
.
symlink
(
path
,
os
.
path
.
join
(
dirname
,
os
.
path
.
basename
(
path
)))
except
OSError
,
e
:
if
e
.
errno
!=
os
.
errno
.
EEXIST
:
raise
def
generateMonitorHalJson
(
self
):
if
self
.
title
:
self
.
monitor_dict
[
"title"
]
=
self
.
title
if
self
.
monitor_url_list
:
self
.
monitor_dict
[
"_links"
]
=
{
"related_monitor"
:
[{
"href"
:
url
}
for
url
in
self
.
monitor_url_list
]}
if
self
.
promise_items
:
service_list
=
[]
for
service_name
,
promise
in
self
.
promise_items
:
service_config
=
promise
[
"configuration"
]
service_dict
=
{}
service_dict
[
"id"
]
=
service_name
service_dict
[
"_links"
]
=
{
"status"
:
{
"href"
:
"/public/%s.status.json"
%
service_name
}}
# hardcoded
tmp
=
softConfigGet
(
service_config
,
"service"
,
"title"
)
if
tmp
:
service_dict
[
"title"
]
=
tmp
interface_path
=
os
.
path
.
join
(
self
.
private_folder
,
service_name
,
"interface/index.html"
)
# hardcoded
if
os
.
path
.
isfile
(
interface_path
):
service_dict
[
"_links"
][
"interface"
]
=
{
"href"
:
"/private/%s/interface/"
%
service_name
}
# hardcoded
else
:
service_dict
[
"_links"
][
"interface"
]
=
{
"href"
:
"/default-promise-interface.html?service_name=%s"
%
service_name
}
# XXX hardcoded
service_list
.
append
(
service_dict
)
self
.
monitor_dict
[
"_embedded"
]
=
{
"service"
:
service_list
}
with
open
(
self
.
monitor_hal_json
,
"w"
)
as
fp
:
json
.
dump
(
self
.
monitor_dict
,
fp
)
def
generateServiceCronEntries
(
self
):
# XXX only if at least one configuration file is modified, then write in the cron
cron_line_list
=
[]
for
service_name
,
promise
in
self
.
promise_items
:
service_config
=
promise
[
"configuration"
]
service_status_path
=
"%s/%s.status.json"
%
(
self
.
public_folder
,
service_name
)
# hardcoded
mkdirAll
(
os
.
path
.
dirname
(
service_status_path
))
command
=
(
"%s %s %s "
%
(
self
.
promise_runner
,
os
.
path
.
join
(
self
.
service_pid_folder
,
"%s.pid"
%
service_name
),
service_status_path
,)
)
+
promise
[
"path"
]
cron_line_list
.
append
(
"%s %s"
%
(
softConfigGet
(
service_config
,
"service"
,
"frequency"
)
or
"* * * * *"
,
command
.
replace
(
"%"
,
"
\
\
%"
),
))
wrapper_path
=
os
.
path
.
join
(
self
.
wraper_folder
,
service_name
)
with
open
(
wrapper_path
,
"w"
)
as
fp
:
fp
.
write
(
"#!/bin/sh
\
n
%s"
%
command
)
# XXX hardcoded, use dash, sh or bash binary!
os
.
chmod
(
wrapper_path
,
stat
.
S_IRUSR
|
stat
.
S_IWUSR
|
stat
.
S_IXUSR
|
stat
.
S_IRGRP
|
stat
.
S_IROTH
)
with
open
(
self
.
crond_folder
+
"/monitor-promises"
,
"w"
)
as
fp
:
fp
.
write
(
"
\
n
"
.
join
(
cron_line_list
))
def
bootstrapMonitor
(
self
):
# create symlinks from service configurations
self
.
promise_items
=
self
.
promise_dict
.
items
()
for
service_name
,
promise
in
self
.
promise_items
:
service_config
=
promise
[
"configuration"
]
public_path_list
=
softConfigGet
(
service_config
,
"service"
,
"public-path-list"
)
private_path_list
=
softConfigGet
(
service_config
,
"service"
,
"private-path-list"
)
if
public_path_list
:
self
.
createSymlinksFromConfig
(
self
.
public_folder
,
public_path_list
.
split
(),
service_name
)
if
private_path_list
:
self
.
createSymlinksFromConfig
(
self
.
private_folder
,
private_path_list
.
split
(),
service_name
)
# create symlinks from monitor.conf
self
.
createSymlinksFromConfig
(
self
.
public_folder
,
self
.
public_path_list
)
self
.
createSymlinksFromConfig
(
self
.
private_folder
,
self
.
private_path_list
)
# generate monitor.json
self
.
monitor_dict
=
{}
self
.
generateMonitorHalJson
()
# put promises to a cron file
self
.
generateServiceCronEntries
()
return
0
if
__name__
==
"__main__"
:
parser
=
parseArguments
()
monitor
=
Monitoring
(
parser
.
config_file
)
sys
.
exit
(
monitor
.
bootstrapMonitor
())
This diff is collapsed.
Click to expand it.
stack/monitor2/run-promise.py
→
stack/monitor2/
scripts/
run-promise.py
View file @
d6634962
#!
{{ python_executable }}
#!
/usr/bin/env python
# -*- coding: utf-8 -*-
import
sys
import
os
import
subprocess
import
json
from
cStringIO
import
StringIO
def
main
():
if
len
(
sys
.
argv
)
<
4
:
...
...
This diff is collapsed.
Click to expand it.
stack/monitor2/status2rss.py
→
stack/monitor2/s
cripts/s
tatus2rss.py
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor-httpd.conf.in
→
stack/monitor2/
templates/
monitor-httpd.conf.in
View file @
d6634962
...
...
@@ -30,6 +30,7 @@ LoadModule authn_file_module modules/mod_authn_file.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
# SSL Configuration
<IfDefine !SSLConfigured>
...
...
@@ -47,6 +48,24 @@ SSLCipherSuite RC4-SHA:HIGH:!ADH
AddType application/hal+json .haljson
SSLEngine On
{% if parameter_dict.has_key('monitor-url-list') -%}
RewriteEngine on
SSLProxyEngine on
ProxyPreserveHost On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
{% set index=1 -%}
{% set monitor_url_list = parameter_dict.get('monitor-url-list').split('\n') -%}
{% for url in monitor_url_list -%}
{% if url.strip() -%}
RewriteRule /monitor{{ index }}/(.*) {{ url }}/$1 [L,P]
{% set index = index + 1 -%}
{% endif -%}
{% endfor -%}
{% endif -%}
ScriptSock {{ parameter_dict.get('cgid-pid-file') }}
<Directory {{ directory.get('www') }}>
SSLVerifyDepth 1
...
...
@@ -55,6 +74,7 @@ ScriptSock {{ parameter_dict.get('cgid-pid-file') }}
# XXX: security????
DirectoryIndex index.html
Options FollowSymLinks
AllowOverride All
Order Deny,Allow
AuthType Basic
AuthName "Private access"
...
...
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor-service.cfg.in
→
stack/monitor2/
templates/
monitor-service.cfg.in
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor.conf.in
→
stack/monitor2/
templates/
monitor.conf.in
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/wrapper.in
→
stack/monitor2/
templates/
wrapper.in
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/default-promise-interface.html
→
stack/monitor2/
web/
default-promise-interface.html
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/web/index.html
0 → 100644
View file @
d6634962
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script
src=
"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"
></script>
<!-- Latest compiled and minified CSS -->
<link
rel=
"stylesheet"
href=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity=
"sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
crossorigin=
"anonymous"
>
<!-- Optional theme -->
<link
rel=
"stylesheet"
href=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css"
integrity=
"sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r"
crossorigin=
"anonymous"
>
<!-- Latest compiled and minified JavaScript -->
<script
src=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
integrity=
"sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
crossorigin=
"anonymous"
></script>
<link
rel=
"stylesheet"
href=
"monitor.css"
/>
<script
src=
"monitor.js"
></script>
</head>
<body>
<noscript>
Please enable javascript on your browser to make this application to work.
</noscript>
</body>
</html>
This diff is collapsed.
Click to expand it.
stack/monitor2/
monitor-
logout.html
→
stack/monitor2/
web/
logout.html
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor-password-interface.html
→
stack/monitor2/
web/
monitor-password-interface.html
View file @
d6634962
File moved
This diff is collapsed.
Click to expand it.
stack/monitor2/monitor.css
→
stack/monitor2/
web/
monitor.css
View file @
d6634962
...
...
@@ -48,3 +48,10 @@ a.as-button:active, button:active {
a
.as-button
:hover
,
button
:hover
{
border-color
:
#777777
;
}
.monitor-section
{
float
:
left
;
table-layout
:
fixed
;
margin-top
:
30px
;
margin-right
:
30px
;
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
stack/monitor2/
monitor.js.in
→
stack/monitor2/
web/monitor.js
View file @
d6634962
/*jslint indent:
2 */
/*jslint indent:2 */
(
function
()
{
"
use strict
"
;
var monitor_title = '
{{ dumps(monitor_title)[5:-1] }}
',
var
monitor_title
=
'
Monitoring interface
'
,
RSS_ICON_DATA_URI
=
[
"
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+CjwhRE9DVFlQR
"
,
"
SBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cu
"
,
...
...
@@ -25,7 +25,8 @@
var
response
=
event
.
target
;
if
(
response
.
status
<
400
)
{
try
{
resolve(JSON.parse(response.responseText));
var
data
=
(
response
.
responseType
===
'
text
'
||
response
.
responseType
===
''
)
?
JSON
.
parse
(
response
.
responseText
)
:
response
.
response
;
resolve
(
data
);
}
catch
(
e
)
{
reject
(
e
);
}
...
...
@@ -95,6 +96,16 @@
return
url
.
href
;
}
function
joinUrl
(
url
,
path
)
{
if
(
path
&&
path
[
0
]
===
'
/
'
)
{
path
=
path
.
slice
(
1
);
}
if
(
url
.
indexOf
(
'
/
'
,
url
.
length
-
1
)
===
-
1
)
{
return
url
+
'
/
'
+
path
;
}
return
url
+
escapeHtml
(
path
);
}
function
escapeHtml
(
html
)
{
return
html
.
replace
(
/&/g
,
"
&
"
).
replace
(
/</g
,
"
<
"
).
replace
(
/>/g
,
"
>
"
).
replace
(
/"/g
,
"
"
"
).
replace
(
/'/g
,
"
'
"
);
}
...
...
@@ -106,6 +117,7 @@
return
;
}
table
=
document
.
createElement
(
"
table
"
);
table
.
className
=
"
monitor-section
"
;
root
.
appendChild
(
table
);
return
Promise
.
all
(
service_list
.
map
(
function
(
service_dict
)
{
var
interface_url
=
softGetProperty
(
service_dict
,
[
"
_links
"
,
"
interface
"
,
"
href
"
]),
...
...
@@ -118,7 +130,8 @@
row
[
5
].
textContent
=
"
No status
"
;
return
;
}
return loadJson(resolveUrl(monitor_url, status_url)).then(function (status_dict) {
var
full_status_url
=
(
monitor_url
===
undefined
)
?
resolveUrl
(
monitor_url
,
status_url
):
joinUrl
(
monitor_url
,
status_url
);
return
loadJson
(
full_status_url
).
then
(
function
(
status_dict
)
{
if
(
status_dict
.
description
)
{
row
[
2
].
title
=
status_dict
.
description
;
}
...
...
@@ -144,8 +157,8 @@
if
(
link
.
href
[
link
.
href
.
length
-
1
]
!==
"
/
"
)
{
link
.
href
+=
"
/
"
;
}
link.href
= resolveUrl(link.href, "monitor.haljson");
return loadJson(
link.href
).catch(function (reason) {
var
haljson_link
=
resolveUrl
(
link
.
href
,
"
monitor.haljson
"
);
return
loadJson
(
haljson_link
).
catch
(
function
(
reason
)
{
div
.
textContent
=
(
reason
&&
(
reason
.
name
+
"
:
"
+
reason
.
message
));
}).
then
(
function
(
monitor_dict
)
{
//monitor_json_list.push(monitor_dict);
...
...
@@ -160,7 +173,7 @@
var
element_list
=
htmlToElementList
([
"
<header>
"
,
"
<a href=
\"\"
class=
\"
as-button
\"
>Refresh</a>
"
,
" <a href=\"/logout\" class=\"as-button\">Logout</a>",
"
<a href=
\"
/logout
.html
\"
class=
\"
as-button
\"
>Logout</a>
"
,
"
<a href=
\"
/feed
\"
><img src=
\"
"
+
RSS_ICON_DATA_URI
+
"
\"
style=
\"
width: 10mm; height: 10mm; vertical-align: middle;
\"
alt=
\"
[RSS Feed]
\"
/></a>
"
,
"
</header>
"
,
"
<h1>
"
+
monitor_title
+
"
</h1>
"
,
...
...
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/ansible-report.cgi.in
deleted
100644 → 0
View file @
b1dcbf77
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/index.cgi.in
deleted
100755 → 0
View file @
b1dcbf77
#!{{ extra_eggs_interpreter }}
import cgi
import cgitb
import Cookie
import base64
import hashlib
import hmac
import jinja2
import os
import subprocess
import urllib
cgitb.enable(display=0, logdir="/tmp/cgi.log")
form = cgi.FieldStorage()
cookie = Cookie.SimpleCookie()
cgi_path = "{{ cgi_directory }}"
monitor_password_path = "{{ monitor_password_path }}"
monitor_password_script_path = "{{ monitor_password_script_path }}"
monitor_apache_password_command = "{{ apache_update_command }}"
monitor_rewrite = "{{ ' '.join(rewrite_element.keys()) }}"
########
# Password functions
#######
def crypt(word, salt="$$"):
salt = salt.split("$")
algo = salt[0] or 'sha1'
if algo in hashlib.algorithms:
H = getattr(hashlib, algo)
elif algo == "plain":
return "%s$%s" % (algo, word)
else:
raise ValueError
rounds = min(max(0, int(salt[1])), 30) if salt[1] else 9
salt = salt[2] or base64.b64encode(os.urandom(12), "./")
h = hmac.new(salt, word, H).digest()
for x in xrange(1, 1
<
<
rounds
)
:
h =
H(h).digest()
return
"%
s
$%
s
$%
s
$%
s
"
%
(
algo
,
rounds
,
salt
,
base64
.
b64encode
(
h
,
"./").
rstrip
("="))
def
is_password_set
()
:
if
not
os
.
path
.
exists
(
monitor_password_path
)
:
return
False
hashed_password =
open(monitor_password_path,
'
r
').
read
()
try:
void
,
algo
,
salt
,
hsh =
hashed_password.split('$')
except
ValueError:
return
False
return
True
def
set_password
(
raw_password
)
:
hashed_password =
crypt(raw_password)
subprocess
.
check_call
(
monitor_apache_password_command
+
"
%
s
"
%
raw_password
,
shell=
True)
open
(
monitor_password_path
,
'
w
').
write
(
hashed_password
)
def
check_password
(
raw_password
)
:
"""
Returns
a
boolean
of
whether
the
raw_password
was
correct
.
Handles
encryption
formats
behind
the
scenes
.
"""
if
not
os
.
path
.
exists
(
monitor_password_path
)
or
not
raw_password:
return
False
hashed_password =
open(monitor_password_path,
'
r
').
read
()
return
hashed_password =
=
crypt
(
raw_password
,
hashed_password
)
###
End
of
password
functions
def
forward_form
()
:
command =
os.path.join(cgi_path,
form
['
posting-script
'].
value
)
params_dict =
{}
for
f
in
form:
params_dict[f] =
form[f].value
del
params_dict
['
posting-script
']
os
.
environ
['
QUERY_STRING
'
] =
urllib.urlencode(params_dict)
try:
if
os
.
access
(
command
,
os
.
X_OK
)
:
print
'\
n
',
subprocess
.
check_output
([
command
])
except
subprocess
.
CalledProcessError:
print
"
There
is
a
problem
with
sub-process
"
pass
def
return_document(command=
None):
if
not
command:
script =
form['script'].value
command =
os.path.join(cgi_path,
script
)
#XXX
this
functions
should
be
called
only
for
display
,
#so
a
priori
it
doesn
'
t
need
form
data
os
.
environ
['
QUERY_STRING
'
] =
''
try:
if
os
.
access
(
command
,
os
.
X_OK
)
:
print
'\
n
',
subprocess
.
check_output
([
command
])
elif
os
.
access
(
command
,
os
.
R_OK
)
:
print
open
(
command
).
read
()
else:
raise
OSError
except
(
subprocess
.
CalledProcessError
,
OSError
)
as
e:
print
"<
p
>
Error :
</p><pre>
%s
</pre>
" % e
def make_menu():
# Transform deep-2 tree in json
folder_list = {}
for folder in os.listdir(cgi_path):
if os.path.isdir(os.path.join(cgi_path, folder)):
folder_list[folder] = []
for folder in folder_list:
for file in os.listdir(os.path.join(cgi_path, folder)):
if os.path.isfile(os.path.join(cgi_path, folder, file)):
folder_list[folder].append(file)
return folder_list
def get_cookie_password():
cookie_string = os.environ.get('HTTP_COOKIE')
if cookie_string:
cookie.load(cookie_string)
try:
return cookie['password'].value
except KeyError:
pass
return None
def set_cookie_password(password):
cookie['password'] = password
print cookie, "; Path=/; HttpOnly"
# Beginning of response
print "Content-Type: text/html"
password = None
# Check if user is logged
if "password_2" in form and "password" in form:
password_2 = form['password_2'].value
password_1 = form['password'].value
password = get_cookie_password()
if not is_password_set() or check_password(password):
if password_2 == password_1:
password = password_1
set_password(password)
set_cookie_password(password)
elif "password" in form:
password = form['password'].value
if is_password_set() and check_password(password):
set_cookie_password(password)
else:
password = get_cookie_password()
print '\n'
if not is_password_set():
return_document(monitor_password_script_path)
elif not check_password(password):
print "
<html><head>
"
print """
<link
rel=
"stylesheet"
href=
"static/pure-min.css"
>
<link
rel=
"stylesheet"
href=
"static/style.css"
>
"""
print "
</head><body>
"
if password is None:
print "
<h1>
This is the monitoring interface
</h1>
"
else:
print "
<h1>
Error
</h1><p>
Wrong password
</p>
"
print """
<p>
Please enter the monitor_password in the next field to access the data
</p>
<form
action=
"/index.cgi"
method=
"post"
class=
"pure-form-aligned"
>
Password :
<input
type=
"password"
name=
"password"
>
<button
type=
"submit"
class=
"pure-button pure-button-primary"
>
Access
</button>
</form>
</body></html>
"""
# redirection to the required script/page
else:
print
if "posting-script" in form:
forward_form()
elif "script" in form:
return_document()
else:
html_base = jinja2.Template(open('{{ index_template }}').read())
print
print html_base.render(tree=make_menu(), default_page="{{ default_page }}", monitor_rewrite=monitor_rewrite)
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/index.html.jinja2
deleted
100644 → 0
View file @
b1dcbf77
<html>
<head>
<title>
Monitoring Interface
</title>
<link
rel=
"stylesheet"
href=
"static/pure-min.css"
>
<link
rel=
"stylesheet"
href=
"static/style.css"
>
<script
src=
"static/jquery-1.10.2.min.js"
></script>
<script
src=
"static/script.js"
></script>
</head>
<body>
<div
id=
"div-menu"
>
<h1>
Monitoring
</h1>
<div
id=
"script-categories"
class=
"pure-menu pure-menu-open"
>
<ul>
{% for category in tree %}
<li
class=
"pure-menu-heading category"
>
{{ category }}
</li>
{% for script in tree[category] %}
<li><a
href=
"{{ category }}/{{ script }}"
class=
"script"
>
{{ script }}
</a></li>
{% endfor %}
{% endfor %}
<li
class=
"pure-menu-heading category"
>
Files
</li>
<li><a
href=
"./private/"
class=
"link"
>
User: admin
</br>
Password is yours
</a></li>
<li
class=
"pure-menu-heading category"
>
Local Service
</li>
{% set rewrite_list = monitor_rewrite.split() %}
{% for path in rewrite_list %}
<li><a
href=
"./rewrite/{{path}}/"
class=
"link"
>
{{path}}
</a></li>
{% endfor %}
</ul>
</div>
</div>
<div
id=
"content"
>
<iframe
src=
"{{ default_page }}"
>
</iframe>
</div>
</body>
</html>
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/monitor-password.cgi.in
deleted
100644 → 0
View file @
b1dcbf77
#!{{ python_executable }}
import cgitb
cgitb.enable()
print "
<html><head>
"
print """
<script
type=
"text/javascript"
src=
"static/jquery-1.10.2.min.js"
></script>
<link
rel=
"stylesheet"
href=
"static/pure-min.css"
>
<link
rel=
"stylesheet"
href=
"static/style.css"
>
"""
print "
</head><body>
"
print "
<h1>
This is the monitoring interface
</h1>
"
print "
<h2>
Please set your password for later access
</h2>
"
print """
<form
action=
"/index.cgi"
method=
"post"
class=
"pure-form-aligned"
>
<div
class=
"pure-control-group"
>
<label
for=
"password"
>
Password*:
</label>
<input
placeholder=
"Set your password"
type=
"password"
name=
"password"
id=
"password"
></br>
</div><div
class=
"pure-control-group"
>
<label
for=
"password"
>
Verify Password*:
</label>
<input
placeholder=
"Verify password"
type=
"password"
name=
"password_2"
id=
"password_2"
></br>
</div><p
id=
"validate-status"
style=
"color:red"
></p>
<div
class=
"pure-controls"
>
<button
id=
"register-button"
type=
"submit"
class=
"pure-button pure-button-primary"
disabled
>
Access
</button></div>
</form>
<script
type=
"text/javascript"
src=
"static/monitor-register.js"
></script>
</body></html>
"""
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/settings.cgi.in
deleted
100755 → 0
View file @
b1dcbf77
#!{{ python_executable }}
import cgi
import cgitb
import ConfigParser
import os
cgitb.enable()
form = cgi.FieldStorage()
print "
<html><head>
"
print "
<link
rel=
\"stylesheet\"
href=
\"static/pure-min.css\"
>
"
print "
<link
rel=
\"stylesheet\"
href=
\"static/style.css\"
>
"
print "
</head><body>
"
config_file = "{{ config_cfg }}"
if not os.path.exists(config_file):
print "Your software does
<b>
not
</b>
embed 0-knowledge. \
This interface is useless in this case
</body></html>
"
exit(0)
parser = ConfigParser.ConfigParser()
parser.read(config_file)
if not parser.has_section('public'):
print "
<p>
Your software does not use 0-knowledge settings.
</p></body></html>
"
exit(0)
for name in form:
if parser.has_option('public', name):
parser.set('public', name, form[name].value)
with open(config_file, 'w') as file:
parser.write(file)
if len(form) > 0:
try:
os.remove("{{ timestamp }}")
except OSError:
pass
print "
<h1>
Values that can be defined :
</h1>
"
print "
<form
action=
\"/index.cgi\"
method=
\"post\"
class=
\"pure-form-aligned\"
>
"
print "
<input
type=
\"hidden\"
name=
\"posting-script\"
value=
\"{{
pwd
}}/{{
this_file
}}\"
>
"
for option in parser.options("public"):
print "
<div
class=
\"pure-control-group\"
>
"
print "
<label
for=
\"%s\"
>
%s
</label>
" % (cgi.escape(option, quote=True), cgi.escape(option))
print "
<input
type=
\"text\"
name=
\"%s\"
value=
\"%s\"
>
" % (cgi.escape(option, quote=True), cgi.escape(parser.get('public', option), quote=True))
print "
</div>
"
print "
<div
class=
\"pure-controls\"
><button
type=
\"submit\"
class=
\"pure-button
\
pure-button-primary
\"
>
Save
</button></div></form>
"
print "
<br><h1>
Other values :
</h1>
"
print "
<form
class=
\"pure-form-aligned\"
>
"
for section in parser.sections():
if section != 'public':
for option in parser.options(section):
print "
<div
class=
\"pure-control-group\"
>
"
print "
<label
for=
\"%s\"
>
%s
</label>
" % (cgi.escape(option, quote=True), cgi.escape(option))
print "
<input
type=
\"text\"
name=
\"%s\"
value=
\"%s\"
readonly
>
" %(cgi.escape(option, quote=True), cgi.escape(parser.get(section, option), quote=True))
print "
</div>
"
print "
</form>
"
print "
</body></html>
"
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/static/monitor-register.js
deleted
100644 → 0
View file @
b1dcbf77
$
(
window
).
load
(
function
(){
$
(
document
).
ready
(
function
()
{
$
(
"
#password_2
"
).
keyup
(
validate
);
});
function
validate
()
{
var
password1
=
$
(
"
#password
"
).
val
();
var
password2
=
$
(
"
#password_2
"
).
val
();
if
(
password1
==
password2
)
{
$
(
"
#register-button
"
).
removeAttr
(
"
disabled
"
);
$
(
"
#validate-status
"
).
attr
(
"
style
"
,
"
display:none
"
);
}
else
{
$
(
"
#register-button
"
).
attr
(
"
disabled
"
,
"
disabled
"
);
$
(
"
#validate-status
"
).
attr
(
"
style
"
,
""
).
text
(
"
Passwords do not match
"
);
}
}
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/static/pure-min.css
deleted
100644 → 0
View file @
b1dcbf77
/*!
Pure v0.3.0
Copyright 2013 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
https://github.com/yui/pure/blob/master/LICENSE.md
*/
/*!
normalize.css v1.1.2 | MIT License | git.io/normalize
Copyright (c) Nicolas Gallagher and Jonathan Neal
*/
/*! normalize.css v1.1.2 | MIT License | git.io/normalize */
article
,
aside
,
details
,
figcaption
,
figure
,
footer
,
header
,
hgroup
,
main
,
nav
,
section
,
summary
{
display
:
block
}
audio
,
canvas
,
video
{
display
:
inline-block
;
*
display
:
inline
;
*
zoom
:
1
}
audio
:not
([
controls
])
{
display
:
none
;
height
:
0
}
[
hidden
]
{
display
:
none
}
html
{
font-size
:
100%
;
-ms-text-size-adjust
:
100%
;
-webkit-text-size-adjust
:
100%
}
html
,
button
,
input
,
select
,
textarea
{
font-family
:
sans-serif
}
body
{
margin
:
0
}
a
:focus
{
outline
:
thin
dotted
}
a
:active
,
a
:hover
{
outline
:
0
}
h1
{
font-size
:
2em
;
margin
:
.67em
0
}
h2
{
font-size
:
1.5em
;
margin
:
.83em
0
}
h3
{
font-size
:
1.17em
;
margin
:
1em
0
}
h4
{
font-size
:
1em
;
margin
:
1.33em
0
}
h5
{
font-size
:
.83em
;
margin
:
1.67em
0
}
h6
{
font-size
:
.67em
;
margin
:
2.33em
0
}
abbr
[
title
]
{
border-bottom
:
1px
dotted
}
b
,
strong
{
font-weight
:
700
}
blockquote
{
margin
:
1em
40px
}
dfn
{
font-style
:
italic
}
hr
{
-moz-box-sizing
:
content-box
;
box-sizing
:
content-box
;
height
:
0
}
mark
{
background
:
#ff0
;
color
:
#000
}
p
,
pre
{
margin
:
1em
0
}
code
,
kbd
,
pre
,
samp
{
font-family
:
monospace
,
serif
;
_font-family
:
'courier new'
,
monospace
;
font-size
:
1em
}
pre
{
white-space
:
pre
;
white-space
:
pre-wrap
;
word-wrap
:
break-word
}
q
{
quotes
:
none
}
q
:before
,
q
:after
{
content
:
''
;
content
:
none
}
small
{
font-size
:
80%
}
sub
,
sup
{
font-size
:
75%
;
line-height
:
0
;
position
:
relative
;
vertical-align
:
baseline
}
sup
{
top
:
-.5em
}
sub
{
bottom
:
-.25em
}
dl
,
menu
,
ol
,
ul
{
margin
:
1em
0
}
dd
{
margin
:
0
0
0
40px
}
menu
,
ol
,
ul
{
padding
:
0
0
0
40px
}
nav
ul
,
nav
ol
{
list-style
:
none
;
list-style-image
:
none
}
img
{
border
:
0
;
-ms-interpolation-mode
:
bicubic
}
svg
:not
(
:root
)
{
overflow
:
hidden
}
figure
{
margin
:
0
}
form
{
margin
:
0
}
fieldset
{
border
:
1px
solid
silver
;
margin
:
0
2px
;
padding
:
.35em
.625em
.75em
}
legend
{
border
:
0
;
padding
:
0
;
white-space
:
normal
;
*
margin-left
:
-7px
}
button
,
input
,
select
,
textarea
{
font-size
:
100%
;
margin
:
0
;
vertical-align
:
baseline
;
*
vertical-align
:
middle
}
button
,
input
{
line-height
:
normal
}
button
,
select
{
text-transform
:
none
}
button
,
html
input
[
type
=
button
],
input
[
type
=
reset
],
input
[
type
=
submit
]
{
-webkit-appearance
:
button
;
cursor
:
pointer
;
*
overflow
:
visible
}
button
[
disabled
],
html
input
[
disabled
]
{
cursor
:
default
}
input
[
type
=
checkbox
],
input
[
type
=
radio
]
{
box-sizing
:
border-box
;
padding
:
0
;
*
height
:
13px
;
*
width
:
13px
}
input
[
type
=
search
]
{
-webkit-appearance
:
textfield
;
-moz-box-sizing
:
content-box
;
-webkit-box-sizing
:
content-box
;
box-sizing
:
content-box
}
input
[
type
=
search
]
::-webkit-search-cancel-button
,
input
[
type
=
search
]
::-webkit-search-decoration
{
-webkit-appearance
:
none
}
button
::-moz-focus-inner
,
input
::-moz-focus-inner
{
border
:
0
;
padding
:
0
}
textarea
{
overflow
:
auto
;
vertical-align
:
top
}
table
{
border-collapse
:
collapse
;
border-spacing
:
0
}
.pure-button
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
line-height
:
normal
;
white-space
:
nowrap
;
vertical-align
:
baseline
;
text-align
:
center
;
cursor
:
pointer
;
-webkit-user-drag
:
none
;
-webkit-user-select
:
none
;
-moz-user-select
:
none
;
-ms-user-select
:
none
;
user-select
:
none
}
.pure-button
::-moz-focus-inner
{
padding
:
0
;
border
:
0
}
.pure-button
{
font-size
:
100%
;
*
font-size
:
90%
;
*
overflow
:
visible
;
padding
:
.5em
1.5em
;
color
:
#444
;
color
:
rgba
(
0
,
0
,
0
,
.8
);
*
color
:
#444
;
border
:
1px
solid
#999
;
border
:
0
rgba
(
0
,
0
,
0
,
0
);
background-color
:
#E6E6E6
;
text-decoration
:
none
;
border-radius
:
2px
;
-webkit-transition
:
.1s
linear
-webkit-box-shadow
;
-moz-transition
:
.1s
linear
-moz-box-shadow
;
-ms-transition
:
.1s
linear
box-shadow
;
-o-transition
:
.1s
linear
box-shadow
;
transition
:
.1s
linear
box-shadow
}
.pure-button-hover
,
.pure-button
:hover
,
.pure-button
:focus
{
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorstr
=
'#00000000'
,
endColorstr
=
'#1a000000'
,
GradientType
=
0
);
background-image
:
-webkit-gradient
(
linear
,
0
0
,
0
100%
,
from
(
transparent
),
color-stop
(
40%
,
rgba
(
0
,
0
,
0
,
.05
)),
to
(
rgba
(
0
,
0
,
0
,
.1
)));
background-image
:
-webkit-linear-gradient
(
transparent
,
rgba
(
0
,
0
,
0
,
.05
)
40%
,
rgba
(
0
,
0
,
0
,
.1
));
background-image
:
-moz-linear-gradient
(
top
,
rgba
(
0
,
0
,
0
,
.05
)
0
,
rgba
(
0
,
0
,
0
,
.1
));
background-image
:
-ms-linear-gradient
(
transparent
,
rgba
(
0
,
0
,
0
,
.05
)
40%
,
rgba
(
0
,
0
,
0
,
.1
));
background-image
:
-o-linear-gradient
(
transparent
,
rgba
(
0
,
0
,
0
,
.05
)
40%
,
rgba
(
0
,
0
,
0
,
.1
));
background-image
:
linear-gradient
(
transparent
,
rgba
(
0
,
0
,
0
,
.05
)
40%
,
rgba
(
0
,
0
,
0
,
.1
))}
.pure-button
:focus
{
outline
:
0
}
.pure-button-active
,
.pure-button
:active
{
box-shadow
:
0
0
0
1px
rgba
(
0
,
0
,
0
,
.15
)
inset
,
0
0
6px
rgba
(
0
,
0
,
0
,
.2
)
inset
}
.pure-button
[
disabled
],
.pure-button-disabled
,
.pure-button-disabled
:hover
,
.pure-button-disabled
:focus
,
.pure-button-disabled
:active
{
border
:
0
;
background-image
:
none
;
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
enabled
=
false
);
filter
:
alpha
(
opacity
=
40
);
-khtml-opacity
:
.4
;
-moz-opacity
:
.4
;
opacity
:
.4
;
cursor
:
not-allowed
;
box-shadow
:
none
}
.pure-button-hidden
{
display
:
none
}
.pure-button
::-moz-focus-inner
{
padding
:
0
;
border
:
0
}
.pure-button-primary
,
.pure-button-selected
,
a
.pure-button-primary
,
a
.pure-button-selected
{
background-color
:
#0078e7
;
color
:
#fff
}
.pure-form
input
[
type
=
text
],
.pure-form
input
[
type
=
password
],
.pure-form
input
[
type
=
email
],
.pure-form
input
[
type
=
url
],
.pure-form
input
[
type
=
date
],
.pure-form
input
[
type
=
month
],
.pure-form
input
[
type
=
time
],
.pure-form
input
[
type
=
datetime
],
.pure-form
input
[
type
=
datetime-local
],
.pure-form
input
[
type
=
week
],
.pure-form
input
[
type
=
number
],
.pure-form
input
[
type
=
search
],
.pure-form
input
[
type
=
tel
],
.pure-form
input
[
type
=
color
],
.pure-form
select
,
.pure-form
textarea
{
padding
:
.5em
.6em
;
display
:
inline-block
;
border
:
1px
solid
#ccc
;
font-size
:
.8em
;
box-shadow
:
inset
0
1px
3px
#ddd
;
border-radius
:
4px
;
-webkit-transition
:
.3s
linear
border
;
-moz-transition
:
.3s
linear
border
;
-ms-transition
:
.3s
linear
border
;
-o-transition
:
.3s
linear
border
;
transition
:
.3s
linear
border
;
-webkit-box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
box-sizing
:
border-box
}
.pure-form
input
[
type
=
text
]
:focus
,
.pure-form
input
[
type
=
password
]
:focus
,
.pure-form
input
[
type
=
email
]
:focus
,
.pure-form
input
[
type
=
url
]
:focus
,
.pure-form
input
[
type
=
date
]
:focus
,
.pure-form
input
[
type
=
month
]
:focus
,
.pure-form
input
[
type
=
time
]
:focus
,
.pure-form
input
[
type
=
datetime
]
:focus
,
.pure-form
input
[
type
=
datetime-local
]
:focus
,
.pure-form
input
[
type
=
week
]
:focus
,
.pure-form
input
[
type
=
number
]
:focus
,
.pure-form
input
[
type
=
search
]
:focus
,
.pure-form
input
[
type
=
tel
]
:focus
,
.pure-form
input
[
type
=
color
]
:focus
,
.pure-form
select
:focus
,
.pure-form
textarea
:focus
{
outline
:
0
;
outline
:
thin
dotted
\
9
;
border-color
:
#129FEA
}
.pure-form
input
[
type
=
file
]
:focus
,
.pure-form
input
[
type
=
radio
]
:focus
,
.pure-form
input
[
type
=
checkbox
]
:focus
{
outline
:
thin
dotted
#333
;
outline
:
1px
auto
#129FEA
}
.pure-form
.pure-checkbox
,
.pure-form
.pure-radio
{
margin
:
.5em
0
;
display
:
block
}
.pure-form
input
[
type
=
text
][
disabled
],
.pure-form
input
[
type
=
password
][
disabled
],
.pure-form
input
[
type
=
email
][
disabled
],
.pure-form
input
[
type
=
url
][
disabled
],
.pure-form
input
[
type
=
date
][
disabled
],
.pure-form
input
[
type
=
month
][
disabled
],
.pure-form
input
[
type
=
time
][
disabled
],
.pure-form
input
[
type
=
datetime
][
disabled
],
.pure-form
input
[
type
=
datetime-local
][
disabled
],
.pure-form
input
[
type
=
week
][
disabled
],
.pure-form
input
[
type
=
number
][
disabled
],
.pure-form
input
[
type
=
search
][
disabled
],
.pure-form
input
[
type
=
tel
][
disabled
],
.pure-form
input
[
type
=
color
][
disabled
],
.pure-form
select
[
disabled
],
.pure-form
textarea
[
disabled
]
{
cursor
:
not-allowed
;
background-color
:
#eaeded
;
color
:
#cad2d3
}
.pure-form
input
[
readonly
],
.pure-form
select
[
readonly
],
.pure-form
textarea
[
readonly
]
{
background
:
#eee
;
color
:
#777
;
border-color
:
#ccc
}
.pure-form
input
:focus:invalid
,
.pure-form
textarea
:focus:invalid
,
.pure-form
select
:focus:invalid
{
color
:
#b94a48
;
border
:
1px
solid
#ee5f5b
}
.pure-form
input
:focus:invalid:focus
,
.pure-form
textarea
:focus:invalid:focus
,
.pure-form
select
:focus:invalid:focus
{
border-color
:
#e9322d
}
.pure-form
input
[
type
=
file
]
:focus:invalid:focus
,
.pure-form
input
[
type
=
radio
]
:focus:invalid:focus
,
.pure-form
input
[
type
=
checkbox
]
:focus:invalid:focus
{
outline-color
:
#e9322d
}
.pure-form
select
{
border
:
1px
solid
#ccc
;
background-color
:
#fff
}
.pure-form
select
[
multiple
]
{
height
:
auto
}
.pure-form
label
{
margin
:
.5em
0
.2em
;
font-size
:
90%
}
.pure-form
fieldset
{
margin
:
0
;
padding
:
.35em
0
.75em
;
border
:
0
}
.pure-form
legend
{
display
:
block
;
width
:
100%
;
padding
:
.3em
0
;
margin-bottom
:
.3em
;
font-size
:
125%
;
color
:
#333
;
border-bottom
:
1px
solid
#e5e5e5
}
.pure-form-stacked
input
[
type
=
text
],
.pure-form-stacked
input
[
type
=
password
],
.pure-form-stacked
input
[
type
=
email
],
.pure-form-stacked
input
[
type
=
url
],
.pure-form-stacked
input
[
type
=
date
],
.pure-form-stacked
input
[
type
=
month
],
.pure-form-stacked
input
[
type
=
time
],
.pure-form-stacked
input
[
type
=
datetime
],
.pure-form-stacked
input
[
type
=
datetime-local
],
.pure-form-stacked
input
[
type
=
week
],
.pure-form-stacked
input
[
type
=
number
],
.pure-form-stacked
input
[
type
=
search
],
.pure-form-stacked
input
[
type
=
tel
],
.pure-form-stacked
input
[
type
=
color
],
.pure-form-stacked
select
,
.pure-form-stacked
label
,
.pure-form-stacked
textarea
{
display
:
block
;
margin
:
.25em
0
}
.pure-form-aligned
input
,
.pure-form-aligned
textarea
,
.pure-form-aligned
select
,
.pure-form-aligned
.pure-help-inline
,
.pure-form-message-inline
{
display
:
inline-block
;
*
display
:
inline
;
*
zoom
:
1
;
vertical-align
:
middle
}
.pure-form-aligned
.pure-control-group
{
margin-bottom
:
.5em
}
.pure-form-aligned
.pure-control-group
label
{
text-align
:
right
;
display
:
inline-block
;
vertical-align
:
middle
;
width
:
10em
;
margin
:
0
1em
0
0
}
.pure-form-aligned
.pure-controls
{
margin
:
1.5em
0
0
10em
}
.pure-form
input
.pure-input-rounded
,
.pure-form
.pure-input-rounded
{
border-radius
:
2em
;
padding
:
.5em
1em
}
.pure-form
.pure-group
fieldset
{
margin-bottom
:
10px
}
.pure-form
.pure-group
input
{
display
:
block
;
padding
:
10px
;
margin
:
0
;
border-radius
:
0
;
position
:
relative
;
top
:
-1px
}
.pure-form
.pure-group
input
:focus
{
z-index
:
2
}
.pure-form
.pure-group
input
:first-child
{
top
:
1px
;
border-radius
:
4px
4px
0
0
}
.pure-form
.pure-group
input
:last-child
{
top
:
-2px
;
border-radius
:
0
0
4px
4px
}
.pure-form
.pure-group
button
{
margin
:
.35em
0
}
.pure-form
.pure-input-1
{
width
:
100%
}
.pure-form
.pure-input-2-3
{
width
:
66%
}
.pure-form
.pure-input-1-2
{
width
:
50%
}
.pure-form
.pure-input-1-3
{
width
:
33%
}
.pure-form
.pure-input-1-4
{
width
:
25%
}
.pure-form
.pure-help-inline
,
.pure-form-message-inline
{
display
:
inline-block
;
padding-left
:
.3em
;
color
:
#666
;
vertical-align
:
middle
;
font-size
:
90%
}
.pure-form-message
{
display
:
block
;
color
:
#666
;
font-size
:
90%
}
@media
only
screen
and
(
max-width
:
480px
){
.pure-form
button
[
type
=
submit
]
{
margin
:
.7em
0
0
}
.pure-form
input
[
type
=
text
],
.pure-form
input
[
type
=
password
],
.pure-form
input
[
type
=
email
],
.pure-form
input
[
type
=
url
],
.pure-form
input
[
type
=
date
],
.pure-form
input
[
type
=
month
],
.pure-form
input
[
type
=
time
],
.pure-form
input
[
type
=
datetime
],
.pure-form
input
[
type
=
datetime-local
],
.pure-form
input
[
type
=
week
],
.pure-form
input
[
type
=
number
],
.pure-form
input
[
type
=
search
],
.pure-form
input
[
type
=
tel
],
.pure-form
input
[
type
=
color
],
.pure-form
label
{
margin-bottom
:
.3em
;
display
:
block
}
.pure-group
input
[
type
=
text
],
.pure-group
input
[
type
=
password
],
.pure-group
input
[
type
=
email
],
.pure-group
input
[
type
=
url
],
.pure-group
input
[
type
=
date
],
.pure-group
input
[
type
=
month
],
.pure-group
input
[
type
=
time
],
.pure-group
input
[
type
=
datetime
],
.pure-group
input
[
type
=
datetime-local
],
.pure-group
input
[
type
=
week
],
.pure-group
input
[
type
=
number
],
.pure-group
input
[
type
=
search
],
.pure-group
input
[
type
=
tel
],
.pure-group
input
[
type
=
color
]
{
margin-bottom
:
0
}
.pure-form-aligned
.pure-control-group
label
{
margin-bottom
:
.3em
;
text-align
:
left
;
display
:
block
;
width
:
100%
}
.pure-form-aligned
.pure-controls
{
margin
:
1.5em
0
0
}
.pure-form
.pure-help-inline
,
.pure-form-message-inline
,
.pure-form-message
{
display
:
block
;
font-size
:
80%
;
padding
:
.2em
0
.8em
}}
.pure-g
{
letter-spacing
:
-.31em
;
*
letter-spacing
:
normal
;
*
word-spacing
:
-.43em
;
text-rendering
:
optimizespeed
;
font-family
:
FreeSans
,
Arimo
,
"Droid Sans"
,
Helvetica
,
Arial
,
sans-serif
;
display
:
-webkit-flex
;
-webkit-flex-flow
:
row
wrap
;
display
:
-ms-flexbox
;
-ms-flex-flow
:
row
wrap
}
.opera-only
:-o-prefocus
,
.pure-g
{
word-spacing
:
-.43em
}
.pure-u
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
letter-spacing
:
normal
;
word-spacing
:
normal
;
vertical-align
:
top
;
text-rendering
:
auto
}
.pure-g
[
class
*=
"pure-u"
]
{
font-family
:
sans-serif
}
.pure-u-1
,
.pure-u-1-2
,
.pure-u-1-3
,
.pure-u-2-3
,
.pure-u-1-4
,
.pure-u-3-4
,
.pure-u-1-5
,
.pure-u-2-5
,
.pure-u-3-5
,
.pure-u-4-5
,
.pure-u-1-6
,
.pure-u-5-6
,
.pure-u-1-8
,
.pure-u-3-8
,
.pure-u-5-8
,
.pure-u-7-8
,
.pure-u-1-12
,
.pure-u-5-12
,
.pure-u-7-12
,
.pure-u-11-12
,
.pure-u-1-24
,
.pure-u-5-24
,
.pure-u-7-24
,
.pure-u-11-24
,
.pure-u-13-24
,
.pure-u-17-24
,
.pure-u-19-24
,
.pure-u-23-24
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
letter-spacing
:
normal
;
word-spacing
:
normal
;
vertical-align
:
top
;
text-rendering
:
auto
}
.pure-u-1
{
width
:
100%
}
.pure-u-1-2
{
width
:
50%
;
*
width
:
49.969%
}
.pure-u-1-3
{
width
:
33.3333%
;
*
width
:
33.3023%
}
.pure-u-2-3
{
width
:
66.6667%
;
*
width
:
66.6357%
}
.pure-u-1-4
{
width
:
25%
;
*
width
:
24.969%
}
.pure-u-3-4
{
width
:
75%
;
*
width
:
74.969%
}
.pure-u-1-5
{
width
:
20%
;
*
width
:
19.969%
}
.pure-u-2-5
{
width
:
40%
;
*
width
:
39.969%
}
.pure-u-3-5
{
width
:
60%
;
*
width
:
59.969%
}
.pure-u-4-5
{
width
:
80%
;
*
width
:
79.969%
}
.pure-u-1-6
{
width
:
16.6667%
;
*
width
:
16.6357%
}
.pure-u-5-6
{
width
:
83.3333%
;
*
width
:
83.3023%
}
.pure-u-1-8
{
width
:
12.5%
;
*
width
:
12.469%
}
.pure-u-3-8
{
width
:
37.5%
;
*
width
:
37.469%
}
.pure-u-5-8
{
width
:
62.5%
;
*
width
:
62.469%
}
.pure-u-7-8
{
width
:
87.5%
;
*
width
:
87.469%
}
.pure-u-1-12
{
width
:
8.3333%
;
*
width
:
8.3023%
}
.pure-u-5-12
{
width
:
41.6667%
;
*
width
:
41.6357%
}
.pure-u-7-12
{
width
:
58.3333%
;
*
width
:
58.3023%
}
.pure-u-11-12
{
width
:
91.6667%
;
*
width
:
91.6357%
}
.pure-u-1-24
{
width
:
4.1667%
;
*
width
:
4.1357%
}
.pure-u-5-24
{
width
:
20.8333%
;
*
width
:
20.8023%
}
.pure-u-7-24
{
width
:
29.1667%
;
*
width
:
29.1357%
}
.pure-u-11-24
{
width
:
45.8333%
;
*
width
:
45.8023%
}
.pure-u-13-24
{
width
:
54.1667%
;
*
width
:
54.1357%
}
.pure-u-17-24
{
width
:
70.8333%
;
*
width
:
70.8023%
}
.pure-u-19-24
{
width
:
79.1667%
;
*
width
:
79.1357%
}
.pure-u-23-24
{
width
:
95.8333%
;
*
width
:
95.8023%
}
.pure-g-r
{
letter-spacing
:
-.31em
;
*
letter-spacing
:
normal
;
*
word-spacing
:
-.43em
;
font-family
:
FreeSans
,
Arimo
,
"Droid Sans"
,
Helvetica
,
Arial
,
sans-serif
;
display
:
-webkit-flex
;
-webkit-flex-flow
:
row
wrap
;
display
:
-ms-flexbox
;
-ms-flex-flow
:
row
wrap
}
.opera-only
:-o-prefocus
,
.pure-g-r
{
word-spacing
:
-.43em
}
.pure-g-r
[
class
*=
"pure-u"
]
{
font-family
:
sans-serif
}
.pure-g-r
img
{
max-width
:
100%
;
height
:
auto
}
@media
(
min-width
:
980px
){
.pure-visible-phone
{
display
:
none
}
.pure-visible-tablet
{
display
:
none
}
.pure-hidden-desktop
{
display
:
none
}}
@media
(
max-width
:
480px
){
.pure-g-r
>
.pure-u
,
.pure-g-r
>[
class
*=
"pure-u-"
]
{
width
:
100%
}}
@media
(
max-width
:
767px
){
.pure-g-r
>
.pure-u
,
.pure-g-r
>[
class
*=
"pure-u-"
]
{
width
:
100%
}
.pure-hidden-phone
{
display
:
none
}
.pure-visible-desktop
{
display
:
none
}}
@media
(
min-width
:
768px
)
and
(
max-width
:
979px
){
.pure-hidden-tablet
{
display
:
none
}
.pure-visible-desktop
{
display
:
none
}}
.pure-menu
ul
{
position
:
absolute
;
visibility
:
hidden
}
.pure-menu.pure-menu-open
{
visibility
:
visible
;
z-index
:
2
;
width
:
100%
}
.pure-menu
ul
{
left
:
-10000px
;
list-style
:
none
;
margin
:
0
;
padding
:
0
;
top
:
-10000px
;
z-index
:
1
}
.pure-menu
>
ul
{
position
:
relative
}
.pure-menu-open
>
ul
{
left
:
0
;
top
:
0
;
visibility
:
visible
}
.pure-menu-open
>
ul
:focus
{
outline
:
0
}
.pure-menu
li
{
position
:
relative
}
.pure-menu
a
,
.pure-menu
.pure-menu-heading
{
display
:
block
;
color
:
inherit
;
line-height
:
1.5em
;
padding
:
5px
20px
;
text-decoration
:
none
;
white-space
:
nowrap
}
.pure-menu.pure-menu-horizontal
>
.pure-menu-heading
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
margin
:
0
;
vertical-align
:
middle
}
.pure-menu.pure-menu-horizontal
>
ul
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
vertical-align
:
middle
;
height
:
2.4em
}
.pure-menu
li
a
{
padding
:
5px
20px
}
.pure-menu-can-have-children
>
.pure-menu-label
:after
{
content
:
'\25B8'
;
float
:
right
;
font-family
:
'Lucida Grande'
,
'Lucida Sans Unicode'
,
'DejaVu Sans'
,
sans-serif
;
margin-right
:
-20px
;
margin-top
:
-1px
}
.pure-menu-can-have-children
>
.pure-menu-label
{
padding-right
:
30px
}
.pure-menu-separator
{
background-color
:
#dfdfdf
;
display
:
block
;
height
:
1px
;
font-size
:
0
;
margin
:
7px
2px
;
overflow
:
hidden
}
.pure-menu-hidden
{
display
:
none
}
.pure-menu-fixed
{
position
:
fixed
;
top
:
0
;
left
:
0
;
width
:
100%
}
.pure-menu-horizontal
li
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
vertical-align
:
middle
}
.pure-menu-horizontal
li
li
{
display
:
block
}
.pure-menu-horizontal
>
.pure-menu-children
>
.pure-menu-can-have-children
>
.pure-menu-label
:after
{
content
:
"\25BE"
}
.pure-menu-horizontal
>
.pure-menu-children
>
.pure-menu-can-have-children
>
.pure-menu-label
{
padding-right
:
30px
}
.pure-menu-horizontal
li
.pure-menu-separator
{
height
:
50%
;
width
:
1px
;
margin
:
0
7px
}
.pure-menu-horizontal
li
li
.pure-menu-separator
{
height
:
1px
;
width
:
auto
;
margin
:
7px
2px
}
.pure-menu.pure-menu-open
,
.pure-menu.pure-menu-horizontal
li
.pure-menu-children
{
background
:
#fff
;
border
:
1px
solid
#b7b7b7
}
.pure-menu.pure-menu-horizontal
,
.pure-menu.pure-menu-horizontal
.pure-menu-heading
{
border
:
0
}
.pure-menu
a
{
border
:
1px
solid
transparent
;
border-left
:
0
;
border-right
:
0
}
.pure-menu
a
,
.pure-menu
.pure-menu-can-have-children
>
li
:after
{
color
:
#777
}
.pure-menu
.pure-menu-can-have-children
>
li
:hover:after
{
color
:
#fff
}
.pure-menu
.pure-menu-open
{
background
:
#dedede
}
.pure-menu
li
a
:hover
,
.pure-menu
li
a
:focus
{
background
:
#eee
}
.pure-menu
li
.pure-menu-disabled
a
:hover
,
.pure-menu
li
.pure-menu-disabled
a
:focus
{
background
:
#fff
;
color
:
#bfbfbf
}
.pure-menu
.pure-menu-disabled
>
a
{
background-image
:
none
;
border-color
:
transparent
;
cursor
:
default
}
.pure-menu
.pure-menu-disabled
>
a
,
.pure-menu
.pure-menu-can-have-children.pure-menu-disabled
>
a
:after
{
color
:
#bfbfbf
}
.pure-menu
.pure-menu-heading
{
color
:
#565d64
;
text-transform
:
uppercase
;
font-size
:
90%
;
margin-top
:
.5em
;
border-bottom-width
:
1px
;
border-bottom-style
:
solid
;
border-bottom-color
:
#dfdfdf
}
.pure-menu
.pure-menu-selected
a
{
color
:
#000
}
.pure-menu.pure-menu-open.pure-menu-fixed
{
border
:
0
;
border-bottom
:
1px
solid
#b7b7b7
}
.pure-paginator
{
letter-spacing
:
-.31em
;
*
letter-spacing
:
normal
;
*
word-spacing
:
-.43em
;
text-rendering
:
optimizespeed
;
list-style
:
none
;
margin
:
0
;
padding
:
0
}
.opera-only
:-o-prefocus
,
.pure-paginator
{
word-spacing
:
-.43em
}
.pure-paginator
li
{
display
:
inline-block
;
*
display
:
inline
;
zoom
:
1
;
letter-spacing
:
normal
;
word-spacing
:
normal
;
vertical-align
:
top
;
text-rendering
:
auto
}
.pure-paginator
.pure-button
{
border-radius
:
0
;
padding
:
.8em
1.4em
;
vertical-align
:
top
;
height
:
1.1em
}
.pure-paginator
.pure-button
:focus
,
.pure-paginator
.pure-button
:active
{
outline-style
:
none
}
.pure-paginator
.prev
,
.pure-paginator
.next
{
color
:
#C0C1C3
;
text-shadow
:
0
-1px
0
rgba
(
0
,
0
,
0
,
.45
)}
.pure-paginator
.prev
{
border-radius
:
2px
0
0
2px
}
.pure-paginator
.next
{
border-radius
:
0
2px
2px
0
}
@media
(
max-width
:
480px
){
.pure-menu-horizontal
{
width
:
100%
}
.pure-menu-children
li
{
display
:
block
;
border-bottom
:
1px
solid
#000
}}
.pure-table
{
border-collapse
:
collapse
;
border-spacing
:
0
;
empty-cells
:
show
;
border
:
1px
solid
#cbcbcb
}
.pure-table
caption
{
color
:
#000
;
font
:
italic
85%
/
1
arial
,
sans-serif
;
padding
:
1em
0
;
text-align
:
center
}
.pure-table
td
,
.pure-table
th
{
border-left
:
1px
solid
#cbcbcb
;
border-width
:
0
0
0
1px
;
font-size
:
inherit
;
margin
:
0
;
overflow
:
visible
;
padding
:
6px
12px
}
.pure-table
td
:first-child
,
.pure-table
th
:first-child
{
border-left-width
:
0
}
.pure-table
thead
{
background
:
#e0e0e0
;
color
:
#000
;
text-align
:
left
;
vertical-align
:
bottom
}
.pure-table
td
{
background-color
:
transparent
}
.pure-table-odd
td
{
background-color
:
#f2f2f2
}
.pure-table-striped
tr
:nth-child
(
2n-1
)
td
{
background-color
:
#f2f2f2
}
.pure-table-bordered
td
{
border-bottom
:
1px
solid
#cbcbcb
}
.pure-table-bordered
tbody
>
tr
:last-child
td
,
.pure-table-horizontal
tbody
>
tr
:last-child
td
{
border-bottom-width
:
0
}
.pure-table-horizontal
td
,
.pure-table-horizontal
th
{
border-width
:
0
0
1px
;
border-bottom
:
1px
solid
#cbcbcb
}
.pure-table-horizontal
tbody
>
tr
:last-child
td
{
border-bottom-width
:
0
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/static/script.js
deleted
100644 → 0
View file @
b1dcbf77
$
(
document
).
ready
(
function
()
{
function
doDataUrl
(
data
)
{
var
frame_content
=
document
.
getElementsByTagName
(
"
iframe
"
)[
0
].
contentWindow
;
var
b64
=
btoa
(
data
);
dataurl
=
'
data:text/html;base64,
'
+
b64
;
$
(
"
iframe
"
).
attr
(
'
src
'
,
dataurl
);
}
if
(
window
.
self
===
window
.
top
)
{
//not in an iframe
$
(
"
.script
"
).
click
(
function
(
e
)
{
e
.
preventDefault
();
var
message
=
$
(
this
).
attr
(
'
href
'
);
var
slash_pos
=
message
.
search
(
'
/
'
);
//let's differenciate kind of script called
if
(
slash_pos
===
-
1
||
slash_pos
===
0
)
{
url
=
message
;
}
else
{
url
=
'
/index.cgi
'
;
}
$
(
"
iframe
"
).
attr
(
'
src
'
,
url
+
'
?script=
'
+
encodeURIComponent
(
message
));
});
$
(
"
.link
"
).
click
(
function
(
e
)
{
e
.
preventDefault
();
var
url
=
$
(
this
).
attr
(
'
href
'
);
$
(
"
iframe
"
).
attr
(
'
src
'
,
url
);
});
}
else
{
//in an iframe
$
(
"
body
"
).
empty
();
}
});
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/static/style.css
deleted
100644 → 0
View file @
b1dcbf77
body
{
padding
:
15px
;
}
.pure-menu
.pure-menu-heading
{
font-size
:
120%
;
}
#content
{
display
:
inline-block
;
min-width
:
72%
;
height
:
97%
;
margin-left
:
30px
;
}
#div-menu
{
display
:
inline-block
;
vertical-align
:
top
;
}
#div-menu
h1
{
text-align
:
center
;
}
iframe
{
width
:
100%
;
height
:
100%
;
margin
:
0px
;
padding
:
0px
;
border-style
:
none
;
}
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/static/welcome.html
deleted
100644 → 0
View file @
b1dcbf77
<html>
<head>
<title>
Welcome to the Monitoring Interface
</title>
<link
rel=
"stylesheet"
href=
"pure-min.css"
>
<link
rel=
"stylesheet"
href=
"style.css"
>
</head>
<body>
<h1>
Welcome to your monitoring interface
</h1>
<p>
From this interface you can monitor, configure your instance
</p>
</body>
</html>
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/status-history.cgi.in
deleted
100644 → 0
View file @
b1dcbf77
#!{{ python_executable }}
import cgi
import datetime
import os
import sqlite3
db_path = '{{ monitor_db_path }}'
status_history_length = '{{ status_history_length }}'
db = sqlite3.connect(db_path)
print """
<html><head>
<link
rel=
"stylesheet"
href=
"static/pure-min.css"
>
<link
rel=
"stylesheet"
href=
"static/style.css"
>
</head><body>
<h1>
Monitor Status History :
</h1>
"""
def get_date_from_timestamp(timestamp):
return datetime.datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
def print_individual_status(timestamp):
print "
<div><h3>
Failure on %s
</h3><ul>
" % get_date_from_timestamp(timestamp)
rows = db.execute("select status, element, output from individual_status where timestamp=?", (timestamp,))
for row in rows:
status, element, output = row
print "
<li>
%s , %s :
</br><pre>
%s
</pre></li>
" % (status, cgi.escape(element), cgi.escape(output))
print "
</ul></div>
"
if not os.path.exists(db_path):
print """No status history found
</p></body></html>
"""
exit(0)
failure_row_list = db.execute("select timestamp from status where status='FAILURE' order by timestamp desc limit ?", status_history_length )
for failure_row in failure_row_list:
timestamp, = failure_row
print_individual_status(timestamp)
print "
</body></html>
"
This diff is collapsed.
Click to expand it.
stack/monitor2/webfile-directory/status.cgi.in
deleted
100755 → 0
View file @
b1dcbf77
#!{{ python_executable }}
import cgi
import cgitb
import json
import os
import subprocess
def refresh():
command = ["{{ monitor_bin }}", "-a"]
subprocess.call(command)
cgitb.enable(display=0, logdir="/tmp/cgi.log")
form = cgi.FieldStorage()
json_file = "{{ json_file }}"
if not os.path.exists(json_file) or "refresh" in form:
refresh()
if not os.path.exists(json_file):
print """
<html><head>
<link
rel=
"stylesheet"
href=
"static/pure-min.css"
>
<link
rel=
"stylesheet"
href=
"static/style.css"
>
</head><body>
<h1>
Monitoring :
</h1>
No status file found
</p></body></html>
"""
exit(0)
result = json.load(open(json_file))
print "
<html><head>
"
print "
<link
rel=
\"stylesheet\"
href=
\"static/pure-min.css\"
>
"
print "
<link
rel=
\"stylesheet\"
href=
\"static/style.css\"
>
"
print "
</head><body>
"
print "
<h1>
Monitoring :
</h1>
"
print "
<form
action=
\"/index.cgi\"
method=
\"post\"
class=
\"pure-form-aligned\"
>
"
print "
<input
type=
\"hidden\"
name=
\"posting-script\"
value=
\"{{
pwd
}}/{{
this_file
}}\"
>
"
print "
<p><em>
Last time of monitoring process : %s
</em></p>
" % (result['datetime'])
del result['datetime']
print "
<div
class=
\"pure-controls\"
><button
type=
\"submit\"
class=
\"pure-button
\
pure-button-primary
\"
name=
\"refresh\"
value=
\"refresh\"
>
Refresh
</button></div></form>
"
print "
<br/>
"
print "
<h2>
These scripts and promises have failed :
</h2>
"
for r in result:
if result[r] != '':
print "
<h3>
%s
</h3><pre
style=
\"padding-left:30px;\"
>
%s
</pre>
" % (cgi.escape(r), cgi.escape(result[r]))
print "
<br/>
"
print "
<h2>
These scripts and promises were successful :
</h2>
"
print "
<ul>
"
for r in result:
if result[r] == '':
print "
<li>
%s
</li>
" % (r)
print "
</ul>
"
print "
</body></html>
"
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment