Commit 15df3830 authored by Tristan Cavelier's avatar Tristan Cavelier

monitor: update api

parent 5571bb14
......@@ -56,12 +56,12 @@ md5sum = 2db5c08c7e8658981b4b1e3f27fd5967
[monitor-bin]
<= monitor-download-base
filename = monitor.py.in
md5sum = a3c673bbd37a98f160f8a10a8fb1b13a
md5sum = 0f9c69954d3b9e952ac6cb63c293f127
[monitor-web-default-promise-interface]
<= monitor-download-base
filename = default-promise-interface.html
md5sum = 1d71746d4afcdc43d663ae8181190254
md5sum = 81fde0e082165ade03c5a9c8abf11136
[monitor-web-index-html]
<= monitor-download-base
......@@ -94,7 +94,7 @@ 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 = 66d13e6e93369a38ff86b8e65abe1cee
md5sum = 008a25e95a87e0e74e8cf4fbefa9ae82
context =
key apache_location apache:location
key gzip_location gzip:location
......
......@@ -14,7 +14,7 @@
var service_name = getServiceName(),
monitor_json_url = "/monitor.haljson",
status_json_url = "/public/" + service_name + "/status.json"; // XXX hardcoded
status_json_url = "/public/" + service_name + ".status.json";
function newDeferred() {
var d = {
......
......@@ -48,6 +48,7 @@ scripts = ${:etc}/run
services = ${:etc}/service
promises = ${:etc}/promise
monitor = ${:srv}/monitor
monitor-promise = ${:etc}/monitor-promise
[monitor-directory]
recipe = slapos.cookbook:mkdirectory
......@@ -223,9 +224,11 @@ rendered = ${directory:scripts}/bootstrap-monitor
context =
raw python_executable {{ python_executable }}
key public_folder monitor-directory:public
key configuration_location monitor-conf:rendered
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
[monitor-run-promise]
recipe = slapos.recipe.template:jinja2
......@@ -246,17 +249,15 @@ curl_path = {{ curl_executable_location }}
[monitor-httpd-promise-conf]
recipe = slapos.recipe.template:jinja2
rendered = ${monitor-directory:services-conf}/monitor-httpd-promise.conf
rendered = ${directory:monitor-promise}/${monitor-httpd-promise:filename}.cfg
template = {{ monitor_httpd_promise_conf }}
mode = 0644
context = section parameter_dict monitor-httpd-promise-conf-parameter
[monitor-httpd-promise-conf-parameter]
title = Monitor httpd listening
name = ${monitor-httpd-promise:filename}
# frequency minute hour day mounth weekday
frequency = * * * * *
#promise-path =
#interface-path =
public-path-list = ${monitor-httpd-conf-parameter:access-log} ${monitor-httpd-conf-parameter:error-log}
#private-path-list =
......@@ -280,5 +281,6 @@ parts =
monitor-conf
start-monitor
ca-httpd
monitor-httpd-promise
monitor-httpd-promise-conf
publish
#!{{ python_executable }}
configuration_location = "{{ configuration_location }}"
# 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 }}"
import sys
import os
......@@ -10,44 +13,33 @@ import subprocess
import threading
import json
import ConfigParser
import traceback
def main():
# initialisation
config = loadConfig([configuration_location])
# search for configurations in monitor.conf.d
configuration_folder_location = configuration_location + ".d"
service_config_list = [
loadConfig(os.path.join(configuration_folder_location, filename))
for filename in os.listdir(configuration_folder_location)
if os.path.isfile(os.path.join(configuration_folder_location, filename))
]
# fill dict of service
service_config_dict = {}
for service_config in service_config_list:
service_config_dict[service_config.get("service", "name")] = service_config
# search for promises and make relation between service_config_list
for filename in os.listdir(promise_folder):
promise_path = os.path.join(promise_folder, filename)
if os.path.isfile(promise_path) and os.access(promise_path, os.X_OK):
service_name = filename
service_config = service_config_dict.get(service_name)
if service_name not in service_config_dict or softConfigGet(service_config, "service", "promise-path"):
service_name = newServiceName(service_name, service_config_dict)
service_config = ConfigParser.ConfigParser()
service_config_list.append(service_config)
service_config_dict[service_name] = service_config
service_config.add_section("service")
service_config.set("service", "name", service_name)
service_config.set("service", "frequency", "* * * * *") # every minutes
service_config.set("service", "promise-path", promise_path)
# filter services without promise-path
service_config_dict = None
service_config_list = [
service_config
for service_config in service_config_list
if softConfigGet(service_config, "service", "promise-path")
]
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")
......@@ -56,57 +48,58 @@ def main():
tmp = softConfigGet(config, "monitor", "monitor-url-list")
if tmp:
monitor_dict["_links"] = {"related_monitor": [{"href": url} for url in tmp.split()]}
if service_config_list:
if promise_items:
service_list = []
monitor_dict["_embedded"] = {"service": service_list}
for service_config in service_config_list:
for service_name, promise in promise_items:
service_config = promise["configuration"]
service_dict = {}
service_list.append(service_dict)
service_name = service_dict["id"] = service_config.get("service", "name")
service_dict["_links"] = {"status": {"href": "/public/%s/status.json" % service_name}}
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
tmp = softConfigGet(service_config, "service", "interface-path")
if tmp:
service_dict["_links"]["interface"] = {"href": "/%s.html" % service_name} # XXX hardcoded
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)
# create symlinks from service configurations
for service_config in service_config_list:
service_name = service_config.get("service", "name")
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)
# put promises to a cron file
# XXX if manifest is modified then: # add manifest to avoid to write every minutes on cron.d...
# 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_config in service_config_list:
service_name = service_config.get("service", "name")
service_status_path = "%s/%s/status.json" % (public_folder, service_name)
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))
service_cron_path = os.path.join(crond_folder, service_name)
cron_line_list.append("%s %s %s %s " % (
service_config.get("service", "frequency"),
softConfigGet(service_config, "service", "frequency") or "* * * * *",
promise_runner_path,
os.path.join(service_pid_folder, "%s.pid" % service_name),
service_status_path,
) + service_config.get("service", "promise-path").replace("%", "\\%"))
) + promise["path"].replace("%", "\\%"))
with open(crond_folder + "/monitor-promises", "w") as fp:
fp.write("\n".join(cron_line_list))
# 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
def loadConfig(pathes):
config = ConfigParser.ConfigParser()
config.read(pathes)
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)
......@@ -127,14 +120,6 @@ def createSymlinksFromConfig(destination_folder_config_tuple, source_list_config
if e.errno != os.errno.EEXIST:
raise
def newServiceName(name, name_dict):
part = name
count = 1
while name in name_dict:
name = part + "_" + str(count)
count += 1
return name
def mkdirAll(path):
try:
os.makedirs(path)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment