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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
iv
slapos
Commits
01d7f0be
Commit
01d7f0be
authored
Sep 15, 2015
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
monitor: make it work
parent
5a60ad67
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
158 additions
and
144 deletions
+158
-144
stack/monitor/buildout.cfg
stack/monitor/buildout.cfg
+42
-23
stack/monitor/instance-monitor.cfg.jinja2.in
stack/monitor/instance-monitor.cfg.jinja2.in
+54
-32
stack/monitor/monitor.conf.in
stack/monitor/monitor.conf.in
+4
-0
stack/monitor/monitor.js.in
stack/monitor/monitor.js.in
+18
-9
stack/monitor/monitor.py.in
stack/monitor/monitor.py.in
+40
-79
stack/monitor/run-promise.py
stack/monitor/run-promise.py
+0
-1
No files found.
stack/monitor/buildout.cfg
View file @
01d7f0be
...
@@ -12,10 +12,20 @@ parts =
...
@@ -12,10 +12,20 @@ parts =
dcron
dcron
monitor-eggs
monitor-eggs
extra-eggs
extra-eggs
monitor-conf
monitor-bin
monitor-bin
monitor-web-index-html
monitor-web-monitor-css
monitor-web-monitor-js
monitor-template
monitor-template
rss-bin
rss-bin
[monitor-download-base]
recipe = hexagonit.recipe.download
download-only = true
url = ${:_profile_base_location_}/${:filename}
mode = 0644
[monitor-eggs]
[monitor-eggs]
recipe = zc.recipe.egg
recipe = zc.recipe.egg
eggs =
eggs =
...
@@ -36,25 +46,45 @@ md5sum = 98c8f6fd81e405b0ad10db07c3776321
...
@@ -36,25 +46,45 @@ md5sum = 98c8f6fd81e405b0ad10db07c3776321
output = ${buildout:directory}/template-make-rss.sh.in
output = ${buildout:directory}/template-make-rss.sh.in
mode = 0644
mode = 0644
[monitor-template]
[monitor-conf]
recipe = slapos.recipe.template
<= monitor-download-base
url = ${:_profile_base_location_}/monitor.cfg.in
filename = monitor.conf.in
output = ${buildout:directory}/monitor.cfg
md5sum = 2db5c08c7e8658981b4b1e3f27fd5967
filename = monitor.cfg
md5sum = 51284c0aeb62eccd37f8a4e1621ee28c
[monitor-bin]
mode = 0644
<= monitor-download-base
filename = monitor.py.in
md5sum = 1a376c4063121db33ffab25b4cd99c76
[monitor-web-index-html]
<= monitor-download-base
filename = index.html
md5sum = 262db07691c145301252a49b6b51d11d
[monitor-web-monitor-css]
<= monitor-download-base
filename = monitor.css
md5sum = a18ab932e5e2e656995f47c7d4a7853a
[monitor-site-template]
[monitor-web-monitor-js]
<= monitor-download-base
filename = monitor.js.in
md5sum = 4f8f1f7f26f589bfdae8fbfee74fc1cc
[monitor-template]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
filename = template-monitor.cfg
filename = template-monitor.cfg
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
rendered = ${buildout:directory}/template-monitor.cfg
rendered = ${buildout:directory}/template-monitor.cfg
md5sum = c
792bdee9049d7061e36c12e2343eb87
md5sum = c
9bcc845671f78bc3e4c544aa84313e3
context =
context =
key apache_location apache:location
key apache_location apache:location
key gzip_location gzip:location
key gzip_location gzip:location
key monitor_static_html monitor-html-static:location
raw monitor_bin ${monitor-bin:location}/${monitor-bin:filename}
raw monitor_bin ${monitor-bin:location}/${monitor-bin:filename}
raw monitor_conf_template ${monitor-conf:location}/${monitor-conf: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_monitor_js ${monitor-web-monitor-js:location}/${monitor-web-monitor-js:filename}
raw curl_executable_location ${curl:location}/bin/curl
raw curl_executable_location ${curl:location}/bin/curl
raw dash_executable_location ${dash:location}/bin/dash
raw dash_executable_location ${dash:location}/bin/dash
raw dcron_executable_location ${dcron:location}/sbin/crond
raw dcron_executable_location ${dcron:location}/sbin/crond
...
@@ -97,21 +127,10 @@ url = https://nexedi.erp5.net/monitor-5c66a4518b466d45cb31cb7e8a225cde20247589.t
...
@@ -97,21 +127,10 @@ url = https://nexedi.erp5.net/monitor-5c66a4518b466d45cb31cb7e8a225cde20247589.t
#md5sum
#md5sum
strip-top-level-dir = true
strip-top-level-dir = true
[monitor-bin]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/${:filename}
download-only = true
md5sum = 68a17075eeeebabd01965be2ee25721d
filename = monitor.py.in
mode = 0644
[run-promise-py]
[run-promise-py]
recipe = hexagonit.recipe.download
<= monitor-download-base
url = ${:_profile_base_location_}/${:filename}
download-only = true
md5sum = 0454e5e28b83da48e52770c977eade8b
filename = run-promise.py
filename = run-promise.py
m
ode = 0644
m
d5sum = 6db26ce13becf8a190e34c14cb8b6f9f
[monitor-httpd-template]
[monitor-httpd-template]
recipe = hexagonit.recipe.download
recipe = hexagonit.recipe.download
...
...
stack/monitor/instance-monitor.cfg.jinja2.in
View file @
01d7f0be
...
@@ -47,11 +47,11 @@ log = ${:var}/log
...
@@ -47,11 +47,11 @@ log = ${:var}/log
scripts = ${:etc}/run
scripts = ${:etc}/run
services = ${:etc}/service
services = ${:etc}/service
promises = ${:etc}/promise
promises = ${:etc}/promise
ssl = ${:etc}/ssl
monitor = ${:srv}/monitor
monitor = ${:srv}/monitor
[monitor-directory]
[monitor-directory]
recipe = slapos.cookbook:mkdirectory
recipe = slapos.cookbook:mkdirectory
bin = ${directory:bin}
etc = ${directory:etc}
etc = ${directory:etc}
run = ${directory:monitor}/run
run = ${directory:monitor}/run
#run = ${directory:scripts}
#run = ${directory:scripts}
...
@@ -59,8 +59,10 @@ pids = ${directory:run}/monitor
...
@@ -59,8 +59,10 @@ pids = ${directory:run}/monitor
cgi-bin = ${directory:monitor}/cgi-bin
cgi-bin = ${directory:monitor}/cgi-bin
public = ${directory:monitor}/public
public = ${directory:monitor}/public
private = ${directory:monitor}/private
private = ${directory:monitor}/private
services = ${directory:services}
services-conf = ${directory:etc}/monitor.conf.d
services-conf = ${directory:etc}/monitor.conf.d
www = ${directory:monitor}/web
www = ${directory:monitor}/web
web-dir = ${directory:monitor}/web
log = ${directory:log}/monitor
log = ${directory:log}/monitor
promises = ${directory:monitor}/promise-scripts
promises = ${directory:monitor}/promise-scripts
...
@@ -80,16 +82,17 @@ log = ${buildout:directory}/var/log
...
@@ -80,16 +82,17 @@ log = ${buildout:directory}/var/log
[ca-directory]
[ca-directory]
recipe = slapos.cookbook:mkdirectory
recipe = slapos.cookbook:mkdirectory
requests = ${directory:ssl}/requests/
root = ${directory:srv}/ssl
private = ${directory:ssl}/private/
requests = ${:root}/requests
certs = ${directory:ssl}/certs/
private = ${:root}/private
newcerts = ${directory:ssl}/newcerts/
certs = ${:root}/certs
crl = ${directory:ssl}/crl/
newcerts = ${:root}/newcerts
crl = ${:root}/crl
[certificate-authority]
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ openssl_executable_location }}
openssl-binary = {{ openssl_executable_location }}
ca-dir = ${
monitor-directory:ca-dir
}
ca-dir = ${
ca-directory:root
}
requests-directory = ${ca-directory:requests}
requests-directory = ${ca-directory:requests}
wrapper = ${monitor-directory:services}/certificate_authority
wrapper = ${monitor-directory:services}/certificate_authority
ca-private = ${ca-directory:private}
ca-private = ${ca-directory:private}
...
@@ -105,17 +108,14 @@ cert-file = ${monitor-httpd-conf:cert-file}
...
@@ -105,17 +108,14 @@ cert-file = ${monitor-httpd-conf:cert-file}
executable = ${httpd-wrapper:wrapper-path}
executable = ${httpd-wrapper:wrapper-path}
wrapper = ${directory:services}/monitor-httpd
wrapper = ${directory:services}/monitor-httpd
[monitor]
[monitor-conf-parameters]
recipe = slapos.cookbook:zero-knowledge.write
title = ${monitor-instance-parameter:monitor-title}
filename = ${monitor-directory:etc}/monitor.conf
title = ${slap-parameter:monitor-title}
service-executable-dir = ${monitor-directory:run}
service-executable-dir = ${monitor-directory:run}
template-service-run = {{ monitor_service_run }}
template-service-run = {{ monitor_service_run }}
public-folder = ${monitor-directory:public}
public-folder = ${monitor-directory:public}
private-folder = ${monitor-directory:private}
private-folder = ${monitor-directory:private}
web-folder = ${monitor-
static-web
:web-dir}
web-folder = ${monitor-
directory
:web-dir}
monitor-hal-json = ${monitor-
static-web
:web-dir}/monitor.haljson
monitor-hal-json = ${monitor-
directory
:web-dir}/monitor.haljson
service-pid-folder = ${monitor-directory:pids}
service-pid-folder = ${monitor-directory:pids}
crond-folder = ${logrotate-directory:cron-entries}
crond-folder = ${logrotate-directory:cron-entries}
public-path-list =
public-path-list =
...
@@ -124,6 +124,12 @@ private-path-list =
...
@@ -124,6 +124,12 @@ private-path-list =
monitor-url-list =
monitor-url-list =
[monitor-conf]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_conf_template }}
rendered = ${directory:etc}/${:filename}
filename = monitor.conf
context = section parameter_dict monitor-conf-parameters
[httpd-monitor-htaccess]
[httpd-monitor-htaccess]
recipe = plone.recipe.command
recipe = plone.recipe.command
...
@@ -134,8 +140,8 @@ user = admin
...
@@ -134,8 +140,8 @@ user = admin
password = admin
password = admin
[monitor-httpd-conf]
[monitor-httpd-conf]
listening-ip = ${
slap-network-information:global
-ipv6}
listening-ip = ${
monitor-instance-parameter:monitor-httpd
-ipv6}
port =
9206
port =
${monitor-instance-parameter:monitor-httpd-port}
pid-file = ${directory:run}/httpd.pid
pid-file = ${directory:run}/httpd.pid
cgid-pid-file = ${directory:run}/cgid.pid
cgid-pid-file = ${directory:run}/cgid.pid
access-log = ${monitor-directory:log}/httpd-access.log
access-log = ${monitor-directory:log}/httpd-access.log
...
@@ -143,7 +149,7 @@ error-log = ${monitor-directory:log}/httpd-error.log
...
@@ -143,7 +149,7 @@ error-log = ${monitor-directory:log}/httpd-error.log
cert-file = ${ca-directory:certs}/httpd.crt
cert-file = ${ca-directory:certs}/httpd.crt
key-file = ${ca-directory:certs}/httpd.key
key-file = ${ca-directory:certs}/httpd.key
htaccess-file = ${httpd-monitor-htaccess:htaccess-path}
htaccess-file = ${httpd-monitor-htaccess:htaccess-path}
url = https://[${
slap-network-information:global
-ipv6}]:${:port}/
url = https://[${
monitor-instance-parameter:monitor-httpd
-ipv6}]:${:port}/
[monitor-httpd-conf]
[monitor-httpd-conf]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
...
@@ -152,7 +158,7 @@ rendered = ${monitor-directory:etc}/monitor-httpd.conf
...
@@ -152,7 +158,7 @@ rendered = ${monitor-directory:etc}/monitor-httpd.conf
mode = 0744
mode = 0744
context =
context =
section directory monitor-directory
section directory monitor-directory
section monitor_parameters monitor
section monitor_parameters monitor
-conf
section monitor_httpd monitor-httpd-conf
section monitor_httpd monitor-httpd-conf
[httpd-wrapper]
[httpd-wrapper]
...
@@ -173,13 +179,24 @@ context =
...
@@ -173,13 +179,24 @@ context =
key content :command
key content :command
command = kill -USR1 $(cat ${monitor-httpd-conf:pid-file})
command = kill -USR1 $(cat ${monitor-httpd-conf:pid-file})
[monitor-static-web]
[monitor-web-index-html]
recipe = plone.recipe.command
recipe = slapos.recipe.template:jinja2
web-dir = ${monitor-directory:www}/
template = {{ monitor_web_index_html }}
command =
rendered = ${monitor-directory:web-dir}/index.html
cp -ax {{monitor_static_html}}/* ${:web-dir}
context =
update-command =
stop-on-error = true
[monitor-web-monitor-css]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_css }}
rendered = ${monitor-directory:web-dir}/monitor.css
context =
[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
[start-monitor]
[start-monitor]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
...
@@ -187,12 +204,14 @@ template = {{ monitor_bin }}
...
@@ -187,12 +204,14 @@ template = {{ monitor_bin }}
rendered = ${directory:scripts}/bootstrap-monitor
rendered = ${directory:scripts}/bootstrap-monitor
context =
context =
raw python_executable {{ python_executable }}
raw python_executable {{ python_executable }}
key configuration_location monitor:filename
key public_folder monitor-directory:public
key configuration_location monitor-conf:rendered
key promise_runner_path monitor-run-promise:rendered
[monitor-run-promise]
[monitor-run-promise]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
template = {{ promise_executor_py }}
template = {{ promise_executor_py }}
rendered = ${directory:bin}/monitor-promise
rendered = ${directory:bin}/monitor-
run-
promise
mode = 700
mode = 700
context =
context =
raw python_executable {{ python_executable }}
raw python_executable {{ python_executable }}
...
@@ -240,19 +259,22 @@ title = Monitor promise httpd
...
@@ -240,19 +259,22 @@ title = Monitor promise httpd
executable-file = ${monitor-monitor-promise:wrapper-path}
executable-file = ${monitor-monitor-promise:wrapper-path}
frequency = */5 * * * *
frequency = */5 * * * *
[
publish-connection-information
]
[
monitor-publish
]
recipe = slapos.cookbook:publish
recipe = slapos.cookbook:publish
monitor_url_v6 = ${monitor-httpd-conf:url}
monitor_url_v6 = ${monitor-httpd-conf:url}
[
slap
-parameter]
[
monitor-instance
-parameter]
monitor-title = Monitoring interface
monitor-title = Monitoring interface
[buildout]
[buildout]
parts =
parts =
monitor-web-index-html
monitor-web-monitor-css
monitor-web-monitor-js
cron-entry-logrotate
cron-entry-logrotate
certificate-authority
certificate-authority
monitor
monitor
-conf
start-monitor
start-monitor
ca-httpd
ca-httpd
conf-monitor-promise
#
conf-monitor-promise
publish-connection-information
monitor-publish
stack/monitor/monitor.conf.in
0 → 100644
View file @
01d7f0be
[monitor]
{% for key, value in parameter_dict.items() -%}
{{ key }} = {{ value.strip().replace("\n", "\n ") }}
{% endfor -%}
stack/monitor/monitor.js
→
stack/monitor/monitor.js
.in
View file @
01d7f0be
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
(function () {
(function () {
"use strict";
"use strict";
var monitor_title = '{{ dumps(monitor_title)[5:-1] }}';
function loadJson(url) {
function loadJson(url) {
/*global XMLHttpRequest */
/*global XMLHttpRequest */
return new Promise(function (resolve, reject) {
return new Promise(function (resolve, reject) {
...
@@ -55,10 +57,15 @@
...
@@ -55,10 +57,15 @@
return [value];
return [value];
}
}
///////////////////
function softGetPropertyAsList(object, path) {
try {
return forceList(getProperty(object, path));
} catch (ignored) {
return [];
}
}
var
monitor_json_list
=
[];
///////////////////
function htmlToElementList(html) {
function htmlToElementList(html) {
/*global document */
/*global document */
...
@@ -80,7 +87,7 @@
...
@@ -80,7 +87,7 @@
}
}
function loadAndRenderMonitorSection(root, monitor_dict, monitor_url) {
function loadAndRenderMonitorSection(root, monitor_dict, monitor_url) {
var
table
,
service_list
=
forceList
(
softGetProperty
(
monitor_dict
,
[
"
_embedded
"
,
"
service
"
])
);
var table, service_list =
softGetPropertyAsList(monitor_dict, ["_embedded", "service"]
);
if (!service_list) {
if (!service_list) {
root.textContent = "";
root.textContent = "";
return;
return;
...
@@ -116,10 +123,10 @@
...
@@ -116,10 +123,10 @@
function loadAndRenderMonitorJson(root) {
function loadAndRenderMonitorJson(root) {
root.textContent = "Loading monitor section...";
root.textContent = "Loading monitor section...";
return loadJson("monitor.haljson").then(function (monitor_dict) {
return loadJson("monitor.haljson").then(function (monitor_dict) {
monitor_json_list
.
push
(
monitor_dict
);
//
monitor_json_list.push(monitor_dict);
root.innerHTML = "";
root.innerHTML = "";
var
loading
=
loadAndRenderMonitorSection
(
root
,
monitor_dict
),
related_monitor_list
=
forceList
(
softGetProperty
(
monitor_dict
,
[
"
_links
"
,
"
related_monitor
"
])
);
var loading = loadAndRenderMonitorSection(root, monitor_dict), related_monitor_list =
softGetPropertyAsList(monitor_dict, ["_links", "related_monitor"]
);
if
(
!
related_monitor_list
)
{
return
loading
;
}
if (!related_monitor_list
.length
) { return loading; }
return Promise.all([loading, Promise.all(related_monitor_list.map(function (link) {
return Promise.all([loading, Promise.all(related_monitor_list.map(function (link) {
var div = htmlToElementList("<div>Loading monitor section...</div>")[0];
var div = htmlToElementList("<div>Loading monitor section...</div>")[0];
root.appendChild(div);
root.appendChild(div);
...
@@ -130,7 +137,7 @@
...
@@ -130,7 +137,7 @@
return loadJson(link.href).catch(function (reason) {
return loadJson(link.href).catch(function (reason) {
div.textContent = (reason && (reason.name + ": " + reason.message));
div.textContent = (reason && (reason.name + ": " + reason.message));
}).then(function (monitor_dict) {
}).then(function (monitor_dict) {
monitor_json_list
.
push
(
monitor_dict
);
//
monitor_json_list.push(monitor_dict);
div.remove();
div.remove();
return loadAndRenderMonitorSection(root, monitor_dict, link.href);
return loadAndRenderMonitorSection(root, monitor_dict, link.href);
});
});
...
@@ -141,15 +148,17 @@
...
@@ -141,15 +148,17 @@
function bootstrap(root) {
function bootstrap(root) {
var element_list = htmlToElementList([
var element_list = htmlToElementList([
"<header><a href=\"\" class=\"as-button\">Refresh</a></header>",
"<header><a href=\"\" class=\"as-button\">Refresh</a></header>",
"
<h1>
KVM Monitoring interface
</h1>
"
,
"<h1>
" + monitor_title + "
</h1>",
"<h2>System health status</h2>",
"<h2>System health status</h2>",
"<p>This interface allow to see the status of several features, it may show problems and sometimes provides a way to fix them.</p>",
"<p>This interface allow to see the status of several features, it may show problems and sometimes provides a way to fix them.</p>",
"<p>Red square means the feature has a problem, green square means it is ok.</p>",
"<p>Red square means the feature has a problem, green square means it is ok.</p>",
"<p>You can click on a feature below to get more precise information.</p>"
"<p>You can click on a feature below to get more precise information.</p>"
].join("\n")), div = document.createElement("div"), tmp;
].join("\n")), div = document.createElement("div"), tmp;
[].forEach.call(element_list, function (element) {
[].forEach.call(element_list, function (element) {
if (element.parentNode.parentNode) { return; }
root.appendChild(element);
root.appendChild(element);
});
});
document.title = monitor_title;
root.appendChild(div);
root.appendChild(div);
/*global alert */
/*global alert */
tmp = loadAndRenderMonitorJson(div);
tmp = loadAndRenderMonitorJson(div);
...
...
stack/monitor/monitor.py.in
View file @
01d7f0be
#!{{ python_executable }}
#!{{ python_executable }}
configuration_location = "{{ configuration_location }}"
configuration_location = "{{ configuration_location }}"
promise_runner_path = "{{ promise_runner_path }}"
public_folder = "{{ public_folder }}"
import sys
import sys
import os
import os
...
@@ -12,9 +14,6 @@ import ConfigParser
...
@@ -12,9 +14,6 @@ import ConfigParser
def main():
def main():
# initialisation
# initialisation
config = loadConfig([configuration_location])
config = loadConfig([configuration_location])
# 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"))
# search for configurations in monitor.conf.d
# search for configurations in monitor.conf.d
configuration_folder_location = configuration_location + ".d"
configuration_folder_location = configuration_location + ".d"
service_config_list = [
service_config_list = [
...
@@ -22,7 +21,7 @@ def main():
...
@@ -22,7 +21,7 @@ def main():
for filename in os.listdir(configuration_folder_location)
for filename in os.listdir(configuration_folder_location)
if os.path.isfile(os.path.join(configuration_folder_location, filename))
if os.path.isfile(os.path.join(configuration_folder_location, filename))
]
]
# search for promises in ...?
# search for promises in ...?
or let promises be on some service conf files?
# XXX see old monitor.py.in
# XXX see old monitor.py.in
# generate monitor.json
# generate monitor.json
monitor_dict = {}
monitor_dict = {}
...
@@ -43,38 +42,39 @@ def main():
...
@@ -43,38 +42,39 @@ def main():
tmp = softConfigGet(service_config, "service", "title")
tmp = softConfigGet(service_config, "service", "title")
if tmp:
if tmp:
service_dict["title"] = tmp
service_dict["title"] = tmp
tmp = softConfigGet(service_config, "service", "interface-
url
")
tmp = softConfigGet(service_config, "service", "interface-
path
")
if tmp:
if tmp:
service_dict["_links"]["interface"] = {"href":
tmp}
service_dict["_links"]["interface"] = {"href":
"/%s.html" % service_name} # XXX hardcoded
with open(config.get("monitor", "monitor-hal-json"), "w") as fp:
with open(config.get("monitor", "monitor-hal-json"), "w") as fp:
json.dump(monitor_dict, fp)
json.dump(monitor_dict, fp)
# create symlinks from service configurations
# create symlinks from service configurations
for service_config in service_config_list:
for service_config in service_config_list:
createSymlinksFromConfig((config, "monitor", "public-folder"), (service_config, "service", "public-path-list"))
service_name = service_config.get("service", "name")
createSymlinksFromConfig((config, "monitor", "private-folder"), (service_config, "service", "private-path-list"))
createSymlinksFromConfig((config, "monitor", "public-folder"), (service_config, "service", "public-path-list"), service_name)
# run scripts according to frequency
createSymlinksFromConfig((config, "monitor", "private-folder"), (service_config, "service", "private-path-list"), service_name)
# XXX
# put promises to a cron file
# XXX if manifest is modified then: # add manifest to avoid to write every minutes on cron.d...
for filename in os.listdir(configuration_folder_location):
service_pid_folder = config.get("monitor", "service-pid-folder")
config_file = os.path.join(configuration_folder_location, filename)
crond_folder = config.get("monitor", "crond-folder")
script_config = loadConfig(config_file)
cron_line_list = []
base_name = script_config.get("service", "name")
for service_config in service_config_list:
pid_file = os.path.join(config.get("monitor", "service-pid-folder"),
service_name = service_config.get("service", "name")
"%s.pid" % base_name)
service_status_path = "%s/%s/status.json" % (public_folder, service_name)
service_run_location = os.path.join(config.get("monitor", "service-executable-dir"),
mkdirAll(os.path.dirname(service_status_path))
base_name)
service_cron_path = os.path.join(crond_folder, service_name)
cron_run_location = os.path.join(config.get("monitor", "crond-folder"),
cron_line_list.append("%s %s %s %s " % (
base_name)
service_config.get("service", "frequency"),
mapping_dict = {"configuration_location": config_file,
promise_runner_path,
"process_pid_file": pid_file}
os.path.join(service_pid_folder, "%s.pid" % service_name),
createServiceWrapper(mapping_dict, service_run_location,
service_status_path,
config.get("monitor", "template-service-run"))
) + service_config.get("service", "promise-path").replace("%", "\\%"))
addCronEntry(cron_run_location,
with open(crond_folder + "/monitor-promises", "w") as fp:
[service_run_location],
fp.write("\n".join(cron_line_list))
script_config.get("service", "frequency"))
# 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"))
return 0
return 0
def loadConfig(pathes):
def loadConfig(pathes):
config = ConfigParser.ConfigParser()
config = ConfigParser.ConfigParser()
config.read(pathes)
config.read(pathes)
...
@@ -86,66 +86,27 @@ def softConfigGet(config, *args, **kwargs):
...
@@ -86,66 +86,27 @@ def softConfigGet(config, *args, **kwargs):
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
return None
return None
def createSymlinksFromConfig(destination_folder_config_tuple, source_list_config_tuple):
def createSymlinksFromConfig(destination_folder_config_tuple, source_list_config_tuple
, service_name=""
):
destination_folder = softConfigGet(*destination_folder_config_tuple)
destination_folder = softConfigGet(*destination_folder_config_tuple)
if destination_folder:
if destination_folder:
source_path_str = softConfigGet(*source_list_config_tuple)
source_path_str = softConfigGet(*source_list_config_tuple)
if source_path_str:
if source_path_str:
for path in source_path_str.split():
for path in source_path_str.split():
dirname = os.path.join(destination_folder, service_name)
try:
try:
os.symlink(path, os.path.join(destination_folder, os.path.basename(path)))
mkdirAll(dirname) # could also raise OSError
os.symlink(path, os.path.join(dirname, os.path.basename(path)))
except OSError, e:
except OSError, e:
if e.errno != os.errno.EEXIST:
if e.errno != os.errno.EEXIST:
raise
raise
def createServiceWrapper(mapping_dict, wrapper_file, template_wrapper):
def mkdirAll(path):
with open(template_wrapper, 'r') as template:
try:
with open(wrapper_file, 'w') as wrapper:
os.makedirs(path)
wrapper.write(template.read() % mapping_dict)
except OSError, e:
os.chmod(wrapper_file, 0700)
if e.errno == os.errno.EEXIST and os.path.isdir(path):
pass
def addCronEntry(file_path, command_list, frequency):
else: raise
with open(file_path, 'w') as cfile:
cfile.write("%s %s" % (frequency, ' '.join(command_list)))
class Popen(subprocess.Popen):
def set_timeout(self, timeout):
self.set_timeout = None # assert we're not called twice
event = threading.Event()
killed = [False] # we just need a mutable
def t():
# do not call wait() or poll() because they're not thread-safe
if not event.wait(timeout) and self.returncode is None:
# race condition if waitpid completes just before the signal sent ?
self.terminate()
killed[0] = True
if event.wait(5):
return
if self.returncode is None:
self.kill() # same race as for terminate ?
t = threading.Thread(target=t)
t.daemon = True
t.start()
def isKilled():
event.set()
t.join()
return killed[0]
return isKilled
def executePath(path):
# XXX script_timeout could be passed as parameters
script_timeout = 3600 # in seconds
with open(os.devnull, 'r+') as f:
p = Popen(command, cwd=instance_path,
env=None if sys.platform == 'cygwin' else {},
stdin=f, stdout=f, stderr=subprocess.PIPE)
killed = p.set_timeout(script_timeout)
stderr = p.communicate()[1]
if killed():
return "Timed Out"
elif p.returncode:
return stderr.strip()
return None
if __name__ == "__main__":
if __name__ == "__main__":
sys.exit(main())
sys.exit(main())
stack/monitor/run-promise.py
View file @
01d7f0be
...
@@ -56,6 +56,5 @@ def executeCommand(args):
...
@@ -56,6 +56,5 @@ def executeCommand(args):
stderr
=
subprocess
.
PIPE
stderr
=
subprocess
.
PIPE
)
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
sys
.
exit
(
main
())
sys
.
exit
(
main
())
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