Commit 8b1572ea authored by Alain Takoudjou's avatar Alain Takoudjou

monitor: remove useless folders and information, always set date with utc timezone

some jio folders are not needed anymore, webdav is only needed for config folder.
Report results are placed in documents folder so they will not be synced automatically (we can get then when needed)
Use UTC timezone in json result instead of local time.
parent f3f875fd
......@@ -12,7 +12,7 @@ import hashlib
import PyRSS2Gen
def getKey(item):
return item.pubDate
return item.source.name
class monitorFeed(object):
......@@ -27,23 +27,24 @@ class monitorFeed(object):
self.feed_url = feed_url
def appendItem(self, item_dict):
event_time = datetime.fromtimestamp(item_dict['change-time'])
event_time = datetime.utcfromtimestamp(item_dict['change-time'])
description = item_dict.get('message', '')
rss_item = PyRSS2Gen.RSSItem(
categories = [item_dict['status']],
source = PyRSS2Gen.Source(item_dict['title'], self.public_url),
title = '[%s] %s' % (item_dict['status'], item_dict['title']),
comments = description,
description = "%s: %s\n%s" % (event_time, item_dict['status'], description),
description = "%s: %s\n\n%s" % (event_time, item_dict['status'], description),
link = self.private_url,
pubDate = event_time,
guid = PyRSS2Gen.Guid(base64.b64encode("%s, %s" % (self.hosting_name,
item_dict['title'])))
guid = PyRSS2Gen.Guid(base64.b64encode("%s, %s, %s" % (self.hosting_name,
item_dict['title'], event_time)),
isPermaLink=False)
)
self.rss_item_list.append(rss_item)
def genrss(self, output_file):
### Build the rss feed
# try to keep the list in the same order
sorted(self.rss_item_list, key=getKey)
rss_feed = PyRSS2Gen.RSS2 (
title = self.instance_name,
......@@ -78,7 +79,7 @@ def generateStatisticsData(stat_file_path, content):
content['date'],
content['state']['success'],
content['state']['error'],
content['state']['warning'])
'')
# append to file
if current_state:
......@@ -98,27 +99,19 @@ def run(args_list):
status_folder = monitor_config.get('monitor', 'public-folder')
base_url = monitor_config.get('monitor', 'base-url')
related_monitor_list = monitor_config.get("monitor", "monitor-url-list").split()
statistic_folder = os.path.join(base_folder, 'data', '.jio_documents')
statistic_folder = os.path.join(base_folder, 'documents')
# need webdav to update parameters
parameter_file = os.path.join(base_folder, 'config', '.jio_documents', 'config.json')
feed_output = os.path.join(status_folder, 'feed')
public_url = "%s/share/jio_public/" % base_url
private_url = "%s/share/jio_private/" % base_url
public_url = "%s/share/public/" % base_url
private_url = "%s/share/private/" % base_url
feed_url = "%s/public/feed" % base_url
error = warning = success = 0
error = success = 0
status = 'OK'
promise_list = []
global_state_file = os.path.join(base_folder, 'monitor.global.json')
public_state_file = os.path.join(status_folder, 'monitor.global.json')
if not os.path.exists(statistic_folder):
try:
os.makedirs(statistic_folder)
except OSError, e:
if e.errno == os.errno.EEXIST and os.path.isdir(statistic_folder):
pass
else: raise
# search for all status files
file_list = filter(os.path.isfile,
glob.glob("%s/*.status.json" % status_folder)
......@@ -129,7 +122,7 @@ def run(args_list):
else:
raise Exception("Cannot read instance configuration at %s" % instance_file)
report_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
report_date = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
monitor_feed = monitorFeed(
config.get('instance', 'name'),
config.get('instance', 'root-name'),
......@@ -147,29 +140,22 @@ def run(args_list):
error += 1
elif tmp_json['status'] == 'OK':
success += 1
elif tmp_json['status'] == 'WARNING':
warning += 1
tmp_json['time'] = tmp_json['start-date'].split(' ')[1]
promise_list.append(tmp_json)
monitor_feed.appendItem(tmp_json)
if error:
status = 'ERROR'
elif warning:
status = 'WARNING'
monitor_feed.genrss(feed_output)
global_state_dict = dict(
status=status,
state={
'error': error,
'success': success,
'warning': warning,
'success': success
},
type='global',
type='global', # bwd compatibility
portal_type='Software Instance',
date=report_date,
_links={"rss_url": {"href": "%s/public/feed" % base_url},
_links={"rss_url": {"href": feed_url},
"public_url": {"href": public_url},
"private_url": {"href": private_url}
},
......@@ -179,13 +165,15 @@ def run(args_list):
'memory_resource': 'monitor_resource_memory.data',
'io_resource': 'monitor_resource_io.data',
'monitor_process_state': 'monitor_resource.status'},
_embedded={'promises': promise_list},
_embedded={},
)
instance_dict = {}
global_state_dict['title'] = config.get('instance', 'name')
# XXX - hosting-title should be removed at some point in favour of specialise_title
global_state_dict['hosting-title'] = config.get('instance', 'root-name')
global_state_dict['specialise_title'] = config.get('instance', 'root-name')
global_state_dict['aggregate_reference'] = config.get('instance', 'computer')
if not global_state_dict['title']:
global_state_dict['title'] = 'Instance Monitoring'
......@@ -199,7 +187,7 @@ def run(args_list):
global_state_dict['_embedded'].update({'instance' : instance_dict})
if related_monitor_list:
global_state_dict['_links']['related_monitor'] = [{'href': "%s/share/jio_public" % url}
global_state_dict['_links']['related_monitor'] = [{'href': "%s/share/public" % url}
for url in related_monitor_list]
if os.path.exists(parameter_file):
......@@ -210,10 +198,10 @@ def run(args_list):
public_state_dict = dict(
status=status,
date=report_date,
_links={'monitor': {'href': '%s/share/jio_private/' % base_url}},
_links={'monitor': {'href': '%s/share/private/' % base_url}},
title=global_state_dict.get('title', '')
)
public_state_dict['hosting-title'] = global_state_dict.get('hosting-title', '')
public_state_dict['specialise_title'] = global_state_dict.get('specialise_title', '')
public_state_dict['_links']['related_monitor'] = global_state_dict['_links'].get('related_monitor', [])
with open(global_state_file, 'w') as fglobal:
......
......@@ -103,6 +103,7 @@ class Monitoring(object):
self.config_folder = os.path.join(self.private_folder, 'config')
self.report_folder = self.private_folder
self.data_folder = os.path.join(self.private_folder, 'documents')
self.promise_output_file = config.get("monitor", "promise-output-file")
self.bootstrap_is_ok = True
......@@ -267,35 +268,22 @@ class Monitoring(object):
return (report_name, "*/%s * * * *" % value)
def configureFolders(self):
# create symlinks from monitor.conf
self.createSymlinksFromConfig(self.public_folder, self.public_path_list)
self.createSymlinksFromConfig(self.private_folder, self.private_path_list)
# configure public and private folder
self.createSymlinksFromConfig(self.webdav_folder, [self.public_folder])
self.createSymlinksFromConfig(self.webdav_folder, [self.private_folder])
#configure jio_documents folder
jio_public = os.path.join(self.webdav_folder, 'jio_public')
jio_private = os.path.join(self.webdav_folder, 'jio_private')
mkdirAll(jio_public)
mkdirAll(jio_private)
createSymlink(self.public_folder,
os.path.join(jio_public, '.jio_documents'))
createSymlink(self.private_folder,
os.path.join(jio_private, '.jio_documents'))
self.data_folder = os.path.join(self.private_folder, 'data', '.jio_documents')
self.document_folder = os.path.join(self.private_folder, 'documents')
config_folder = os.path.join(self.config_folder, '.jio_documents')
config_jio_folder = os.path.join(self.config_folder, '.jio_documents')
mkdirAll(self.data_folder)
mkdirAll(config_folder)
mkdirAll(config_jio_folder)
createSymlink(os.path.join(self.private_folder, 'data'),
os.path.join(jio_private, 'data'))
createSymlink(self.config_folder, os.path.join(jio_private, 'config'))
createSymlink(self.data_folder, self.document_folder)
# Cleanup private folder
for file in glob.glob("%s/*.history.json" % self.private_folder):
# Cleanup private folder, remove files that should not be synced from private root dir
cleanup_file_list = glob.glob("%s/*.history.json" % self.private_folder)
cleanup_file_list.extend(glob.glob("%s/*.report.json" % self.private_folder))
for file in cleanup_file_list:
try:
os.unlink(file)
except OSError:
......@@ -305,7 +293,6 @@ class Monitoring(object):
config_folder = os.path.join(self.config_folder, '.jio_documents')
parameter_config_file = os.path.join(config_folder, 'config.parameters.json')
parameter_file = os.path.join(config_folder, 'config.json')
#mkdirAll(config_folder)
parameter_list = self.readInstanceConfiguration()
description_dict = {}
......@@ -336,10 +323,12 @@ class Monitoring(object):
def generateOpmlFile(self, feed_url_list, output_file):
if os.path.exists(output_file):
creation_date = datetime.fromtimestamp(os.path.getctime(output_file)).utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000")
creation_date = datetime.utcfromtimestamp(os.path.getctime(output_file))\
.strftime("%a, %d %b %Y %H:%M:%S +0000")
modification_date = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000")
else:
creation_date = modification_date = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000")
creation_date = modification_date = datetime.utcnow()\
.strftime("%a, %d %b %Y %H:%M:%S +0000")
opml_content = OPML_START % {'creation_date': creation_date,
'modification_date': modification_date,
......@@ -349,13 +338,13 @@ class Monitoring(object):
opml_content += OPML_OUTLINE_FEED % {'title': self.title,
'html_url': self.public_url + '/feed',
'xml_url': self.public_url + '/feed',
'global_url': "%s/jio_private/" % self.webdav_url}
'global_url': "%s/private/" % self.webdav_url}
for feed_url in feed_url_list:
opml_content += OPML_OUTLINE_FEED % {
'title': self.getMonitorTitleFromUrl(feed_url + "/share/public/"),
'html_url': feed_url + '/public/feed',
'xml_url': feed_url + '/public/feed',
'global_url': "%s/share/jio_private/" % feed_url}
'global_url': "%s/share/private/" % feed_url}
opml_content += OPML_END
......@@ -384,18 +373,17 @@ class Monitoring(object):
report_script = os.path.join(self.report_script_folder, filename)
if os.path.isfile(report_script) and os.access(report_script, os.X_OK):
report_name, frequency = self.getReportInfoFromFilename(filename)
# report_name = os.path.splitext(filename)[0]
report_json_path = "%s.report.json" % report_name
report_json_name = "%s.report.json" % report_name
report_cmd_line = [
frequency,
self.promise_runner,
'--pid_path "%s"' % os.path.join(self.service_pid_folder,
"%s.pid" % filename),
'--output "%s"' % os.path.join(self.report_folder,report_json_path),
'--output "%s"' % os.path.join(self.data_folder, report_json_name),
'--promise_script "%s"' % report_script,
'--promise_name "%s"' % report_name,
'--monitor_url "%s/jio_private/"' % self.webdav_url, # XXX hardcoded,
'--monitor_url "%s/private/"' % self.webdav_url, # XXX hardcoded,
'--history_folder "%s"' % self.data_folder,
'--instance_name "%s"' % self.title,
'--hosting_name "%s"' % self.root_title,
......@@ -436,7 +424,7 @@ class Monitoring(object):
'--promise_folder "%s"' % self.promise_folder,
'--timeout_file "%s"' % self.promise_timeout_file,
'--monitor_promise_folder "%s"' % self.monitor_promise_folder,
'--monitor_url "%s/jio_private/"' % self.webdav_url, # XXX hardcoded,
'--monitor_url "%s/private/"' % self.webdav_url, # XXX hardcoded,
'--history_folder "%s"' % self.public_folder,
'--instance_name "%s"' % self.title,
'--hosting_name "%s"' % self.root_title]
......@@ -477,10 +465,6 @@ class Monitoring(object):
with open(self.pid_file, 'w') as pid_file:
pid_file.write(str(os.getpid()))
# create symlinks from monitor.conf
self.createSymlinksFromConfig(self.public_folder, self.public_path_list)
self.createSymlinksFromConfig(self.private_folder, self.private_path_list)
self.configureFolders()
# Generate OPML file
......
......@@ -7,6 +7,7 @@ import subprocess
import json
import psutil
import time
from datetime import datetime
from shutil import copyfile
import glob
import argparse
......@@ -68,9 +69,10 @@ class RunPromise(object):
def runpromise(self):
if self.config.promise_folder:
# run all promises from the given folder
# run all promises from the given folder in a synchronous way
return self.runpromise_synchronous()
# run the promises in a new process
if os.path.exists(self.config.pid_path):
with open(self.config.pid_path, "r") as pidfile:
try:
......@@ -84,7 +86,7 @@ class RunPromise(object):
with open(self.config.pid_path, "w") as pidfile:
process = self.executeCommand(self.config.promise_script)
ps_process = psutil.Process(process.pid)
start_date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ps_process.create_time()))
start_date = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
pidfile.write(str(process.pid))
status_json = self.generateStatusJsonFromProcess(process, start_date=start_date)
......@@ -94,6 +96,8 @@ class RunPromise(object):
status_json['instance'] = self.config.instance_name
status_json['hosting_subscription'] = self.config.hosting_name
status_json['type'] = self.config.promise_type
status_json['portal_type'] = "promise" if \
self.config.promise_type == "status" else self.config.promise_type
# Save the lastest status change date (needed for rss)
status_json['change-time'] = ps_process.create_time()
......@@ -112,12 +116,19 @@ class RunPromise(object):
self.config.history_folder,
self.config.promise_type
)
with open(self.config.output, "w") as outputfile:
# write the promise in a tmp file the move to promise output file
# this reduce conflict error on read/write at sametime
output_tmp = '%s.tmp' % self.config.output
with open(output_tmp, "w") as outputfile:
json.dump(status_json, outputfile)
os.rename(output_tmp, self.config.output)
os.remove(self.config.pid_path)
def runpromise_synchronous(self):
def runpromise_synchronous(self):
"""
run all promises in sequential ways
"""
if os.path.exists(self.config.pid_path):
# Check if another run promise is running
with open(self.config.pid_path) as fpid:
......@@ -155,14 +166,19 @@ class RunPromise(object):
for status_dict in status_list:
status_dict.update(base_dict)
if previous_state_dict.has_key(status_dict['title']):
status, time = previous_state_dict[status_dict['title']].split('#')
status, change_time = previous_state_dict[status_dict['title']].split('#')
if status_dict['status'] == status:
status_dict['change-time'] = float(time)
status_dict['change-time'] = float(change_time)
promise_result_file = os.path.join(self.config.output,
"%s.status.json" % status_dict['title'])
with open(promise_result_file, "w") as outputfile:
# write the promise in a tmp file the move to promise output file
# this reduce conflict error on read/write at sametime
promise_tmp_file = '%s.tmp' % promise_result_file
with open(promise_tmp_file, "w") as outputfile:
json.dump(status_dict, outputfile)
os.rename(promise_tmp_file, promise_result_file)
new_state_dict[status_dict['title']] = '%s#%s' % (status_dict['status'],
status_dict['change-time'])
self.updateStatusHistoryFolder(
......@@ -216,6 +232,7 @@ class RunPromise(object):
status_dict.pop('title', '')
status_dict.pop('instance', '')
status_dict.pop('type', '')
status_dict.pop('portal_type', '')
with open (history_file, mode="r+") as f_history:
f_history.seek(0,2)
......@@ -298,9 +315,10 @@ class RunPromise(object):
promise_name = os.path.basename(command[0])
result_dict = {
"status": "ERROR",
"type": "status",
"type": "status", # keep compatibility
"portal_type": "promise",
"title": promise_name,
"start-date" : time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())),
"start-date" : datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S'),
"change-time": time.time()
}
......@@ -333,7 +351,7 @@ class RunPromise(object):
message = process_handler.stderr.read()
if message is None:
message = process_handler.stdout.read() or ""
message += '\nPROMISE TIME OUT AFTER %s SECONDS' % self.promise_timeout
message += '\nPROMISE TIMED OUT AFTER %s SECONDS' % self.promise_timeout
result_dict["message"] = message
promise_result_list.append(result_dict)
......
......@@ -76,7 +76,7 @@ promise-output-file = %(base_dir)s/monitor-bootstrap-status
promise-runner = %(promise_run_script)s
"""
self.opml_outline = """<outline text="Monitoring RSS Feed list"><outline text="%(title)s" title="%(title)s" type="rss" version="RSS" htmlUrl="%(base_url)s/public/feed" xmlUrl="%(base_url)s/public/feed" url="%(base_url)s/share/jio_private/" />"""
self.opml_outline = """<outline text="%(title)s" title="%(title)s" type="rss" version="RSS" htmlUrl="%(base_url)s/public/feed" xmlUrl="%(base_url)s/public/feed" url="%(base_url)s/share/private/" />"""
def tearDown(self):
if os.path.exists(self.base_dir):
......@@ -122,12 +122,12 @@ promise-runner = %(promise_run_script)s
promise_command_list = cronf.read()
if not sequential:
promise_entry = '* * * * * sleep $((1 + RANDOM %% 20)) && %(promise_run_script)s --pid_path "%(promise_runner_pid)s" --output "%(public_folder)s" --promise_folder "%(promise_folder)s" --timeout_file "None" --monitor_promise_folder "%(monitor_promise_folder)s" --monitor_url "%(base_url)s/share/jio_private/" --history_folder "%(base_dir)s/public" --instance_name "%(title)s" --hosting_name "%(root_title)s"'
promise_entry = '* * * * * sleep $((1 + RANDOM %% 20)) && %(promise_run_script)s --pid_path "%(promise_runner_pid)s" --output "%(public_folder)s" --promise_folder "%(promise_folder)s" --timeout_file "None" --monitor_promise_folder "%(monitor_promise_folder)s" --monitor_url "%(base_url)s/share/private/" --history_folder "%(base_dir)s/public" --instance_name "%(title)s" --hosting_name "%(root_title)s"'
entry_line = promise_entry % self.monitor_config_dict
self.assertTrue(entry_line in promise_command_list,
"%s not in %s" %(entry_line, promise_command_list))
else:
promise_entry = '* * * * * sleep $((1 + RANDOM %% 30)) &&%(promise_run_script)s --pid_path "%(promise_pid)s" --output "%(promise_output)s" --promise_script "%(promise_executable)s" --promise_name "%(promise_name)s" --monitor_url "%(base_url)s/share/jio_private/" --history_folder "%(base_dir)s/public" --instance_name "%(title)s" --hosting_name "%(root_title)s"'
promise_entry = '* * * * * sleep $((1 + RANDOM %% 30)) &&%(promise_run_script)s --pid_path "%(promise_pid)s" --output "%(promise_output)s" --promise_script "%(promise_executable)s" --promise_name "%(promise_name)s" --monitor_url "%(base_url)s/share/private/" --history_folder "%(base_dir)s/public" --instance_name "%(title)s" --hosting_name "%(root_title)s"'
promise_dir = os.path.join(self.base_dir, 'promise')
for filename in os.listdir(promise_dir):
......@@ -142,9 +142,9 @@ promise-runner = %(promise_run_script)s
self.assertTrue(entry_line in promise_command_list)
def check_report(self):
promise_entry = '* * * * * %(promise_run_script)s --pid_path "%(promise_pid)s" --output "%(promise_output)s" --promise_script "%(promise_executable)s" --promise_name "%(promise_name)s" --monitor_url "%(base_url)s/share/jio_private/" --history_folder "%(data_dir)s" --instance_name "%(title)s" --hosting_name "%(root_title)s" --promise_type "report"'
promise_entry = '* * * * * %(promise_run_script)s --pid_path "%(promise_pid)s" --output "%(promise_output)s" --promise_script "%(promise_executable)s" --promise_name "%(promise_name)s" --monitor_url "%(base_url)s/share/private/" --history_folder "%(data_dir)s" --instance_name "%(title)s" --hosting_name "%(root_title)s" --promise_type "report"'
promise_dir = os.path.join(self.base_dir, 'monitor-report')
data_dir = os.path.join(self.base_dir, 'private', 'data', '.jio_documents')
data_dir = os.path.join(self.base_dir, 'private', 'documents')
promise_cron = os.path.join(self.base_dir, 'cron.d', 'monitor-reports')
self.assertTrue(os.path.exists(promise_cron))
......@@ -154,7 +154,7 @@ promise-runner = %(promise_run_script)s
for filename in os.listdir(promise_dir):
promise_dict = dict(
promise_pid=os.path.join(self.base_dir, 'run', '%s.pid' % filename),
promise_output=os.path.join(self.base_dir, 'private', '%s.report.json' % filename),
promise_output=os.path.join(data_dir, '%s.report.json' % filename),
promise_executable=os.path.join(promise_dir, filename),
promise_name=filename,
data_dir=data_dir
......@@ -239,9 +239,6 @@ promise-runner = %(promise_run_script)s
self.checkOPML([self.monitor_config_dict['base_url']])
# Check jio webdav folder
self.assertTrue(os.path.exists(os.path.join(self.base_dir, 'webdav/jio_public')))
self.assertTrue(os.path.exists(os.path.join(self.base_dir, 'webdav/jio_private')))
# check symlink configured
self.check_symlink(folder_one, os.path.join(self.base_dir, 'public', 'folderOne'))
self.check_symlink(folder_two, os.path.join(self.base_dir, 'public', 'folderTwo'))
......@@ -258,7 +255,8 @@ promise-runner = %(promise_run_script)s
# check that configuration folder exist
self.assertTrue(os.path.exists(os.path.join(self.base_dir, 'private/config')))
self.assertTrue(os.path.exists(os.path.join(self.base_dir, 'private/data')))
# Check jio webdav folder
self.assertTrue(os.path.exists(os.path.join(self.base_dir, 'private/config/.jio_documents')))
self.assertTrue(os.path.exists(os.path.join(self.base_dir, 'private/documents')))
def test_monitor_bootstrap_promises(self):
......
# -*- coding: utf-8 -*-
import os, time
import sys
import shutil
import tempfile
import unittest
import json
from slapos.monitor import globalstate
from slapos.monitor.runpromise import RunPromise, parseArguments
from slapos.monitor.monitor import Monitoring
class MonitorGlobalTest(unittest.TestCase):
def setUp(self):
self.base_dir = tempfile.mkdtemp()
os.mkdir(os.path.join(self.base_dir, 'promise'))
os.mkdir(os.path.join(self.base_dir, 'monitor-promise'))
os.mkdir(os.path.join(self.base_dir, 'public'))
os.mkdir(os.path.join(self.base_dir, 'private'))
os.mkdir(os.path.join(self.base_dir, 'cron.d'))
os.mkdir(os.path.join(self.base_dir, 'logrotate.d'))
os.mkdir(os.path.join(self.base_dir, 'monitor-report'))
os.mkdir(os.path.join(self.base_dir, 'webdav'))
os.mkdir(os.path.join(self.base_dir, 'run'))
self.writeContent(os.path.join(self.base_dir, 'param'), '12345')
self.writeContent(os.path.join(self.base_dir, '.monitor_pwd'), 'bcuandjy')
self.writeContent(os.path.join(self.base_dir, 'test-httpd-cors.cfg'), '')
self.writeContent(os.path.join(self.base_dir, 'monitor-htpasswd'), '12345')
self.writeContent(os.path.join(self.base_dir, 'instance.cfg'), """[instance]
name = Monitor
root-name = Monitor ROOT
computer = COMP-1234
ipv4 = 10.0.151.118
ipv6 = 2001:34c:1254:df3:89::5df3
software-release = http://some.url.com/software.cfg
software-type = default
partition = slappart10""")
self.monitor_config_file = os.path.join(self.base_dir, 'monitor.conf')
self.public_dir = os.path.join(self.base_dir, 'public')
self.private_dir = os.path.join(self.base_dir, 'private')
self.monitor_config_dict = dict(
base_dir=self.base_dir,
root_title="Monitor ROOT",
title="Monitor",
url_list="",
base_url="https://monitor.test.com",
monitor_promise_folder=os.path.join(self.base_dir, 'monitor-promise'),
promise_folder=os.path.join(self.base_dir, 'promise'),
promise_runner_pid=os.path.join(self.base_dir, 'run', 'monitor-promises.pid'),
public_folder=os.path.join(self.base_dir, 'public'),
public_path_list="",
private_path_list="",
promise_run_script="/bin/echo",
collect_run_script="/bin/echo",
statistic_script="/bin/echo"
)
self.monitor_conf = """[monitor]
parameter-file-path = %(base_dir)s/knowledge0.cfg
promise-folder = %(base_dir)s/promise
service-pid-folder = %(base_dir)s/run
monitor-promise-folder = %(base_dir)s/monitor-promise
private-folder = %(base_dir)s/private
public-folder = %(base_dir)s/public
public-path-list = %(public_path_list)s
private-path-list = %(private_path_list)s
crond-folder = %(base_dir)s/cron.d
logrotate-folder = %(base_dir)s/logrotate.d
report-folder = %(base_dir)s/monitor-report
root-title = %(root_title)s
pid-file = %(base_dir)s/monitor.pid
parameter-list =
raw monitor-user admin
file sample %(base_dir)s/param
htpasswd monitor-password %(base_dir)s/.monitor_pwd admin %(base_dir)s/monitor-htpasswd
httpdcors cors-domain %(base_dir)s/test-httpd-cors.cfg /bin/echo
webdav-folder = %(base_dir)s/webdav
collect-script = %(collect_run_script)s
statistic-script = %(statistic_script)s
python = python
monitor-url-list = %(url_list)s
collector-db =
base-url = %(base_url)s
title = %(title)s
service-pid-folder = %(base_dir)s/run
promise-output-file = %(base_dir)s/monitor-bootstrap-status
promise-runner = %(promise_run_script)s
"""
def tearDown(self):
if os.path.exists(self.base_dir):
shutil.rmtree(self.base_dir)
def writeContent(self, file_path, config):
with open(file_path, 'w') as cfg:
cfg.write(config)
def writePromise(self, name, success=True):
if success:
result_dict = {'output': 'success', 'code': 0}
else:
result_dict = {'output': 'error', 'code': 1}
content = """#!/bin/sh
echo "%(output)s"
exit %(code)s
""" % result_dict
promise_path = os.path.join(self.base_dir, 'promise', name)
self.writeContent(promise_path, content)
os.chmod(promise_path, 0755)
return promise_path
def getPromiseParser(self):
pid_path = os.path.join(self.base_dir, 'run', 'monitor-promise.pid')
promise_cmd = [
'--pid_path',
'%s' % pid_path, '--output', os.path.join(self.base_dir, 'public'),
'--promise_folder', os.path.join(self.base_dir, 'promise'),
'--monitor_promise_folder', os.path.join(self.base_dir, 'monitor-promise'),
'--promise_type', 'status',
'--monitor_url', 'https://monitor.test.com/share/private/',
'--history_folder', os.path.join(self.base_dir, 'public'),
'--instance_name', 'Monitor', '--hosting_name', 'Monitor ROOT']
arg_parser = parseArguments()
return arg_parser.parse_args(promise_cmd)
def test_monitor_instance_state(self):
config_content = self.monitor_conf % self.monitor_config_dict
self.writeContent(self.monitor_config_file, config_content)
instance = Monitoring(self.monitor_config_file)
instance.bootstrapMonitor()
self.writePromise('promise_1')
self.writePromise('promise_2', success=False)
self.writePromise('promise_3', success=False)
self.writePromise('promise_4')
parser = self.getPromiseParser()
promise_runner = RunPromise(parser)
promise_runner.runpromise()
self.assertTrue(os.path.exists(os.path.join(self.public_dir, 'promise_1.status.json')))
self.assertTrue(os.path.exists(os.path.join(self.public_dir, 'promise_2.status.json')))
self.assertTrue(os.path.exists(os.path.join(self.public_dir, 'promise_3.status.json')))
self.assertTrue(os.path.exists(os.path.join(self.public_dir, 'promise_4.status.json')))
# generate instance state files
globalstate.run([self.monitor_config_file, os.path.join(self.base_dir, 'instance.cfg')])
self.assertTrue(os.path.exists(os.path.join(self.public_dir, 'feed')))
self.assertTrue(os.path.exists(os.path.join(self.public_dir, 'monitor.global.json')))
self.assertTrue(os.path.exists(os.path.join(self.private_dir, 'monitor.global.json')))
expected_result = """{
"status": "ERROR",
"_embedded": {
"instance": {
"partition": "slappart10",
"ipv6": "2001:34c:1254:df3:89::5df3",
"computer": "COMP-1234",
"ipv4": "10.0.151.118",
"software-release": "http://some.url.com/software.cfg",
"software-type": "default"
}
},
"parameters": [{
"key": "",
"value": "admin",
"title": "monitor-user"
}, {
"key": "sample",
"value": "12345",
"title": "sample"
}, {
"key": "monitor-password",
"value": "bcuandjy",
"title": "monitor-password"
}, {
"key": "cors-domain",
"value": "",
"title": "cors-domain"
}],
"title": "Monitor",
"data": {
"process_state": "monitor_process_resource.status",
"io_resource": "monitor_resource_io.data",
"state": "monitor_state.data",
"memory_resource": "monitor_resource_memory.data",
"process_resource": "monitor_resource_process.data",
"monitor_process_state": "monitor_resource.status"
},
"portal_type": "instance_state",
"state": {
"success": 2,
"error": 2
},
"_links": {
"rss_url": {
"href": "https://monitor.test.com/public/feed"
},
"public_url": {
"href": "https://monitor.test.com/share/public/"
},
"private_url": {
"href": "https://monitor.test.com/share/private/"
}
},
"computer_reference": "COMP-1234",
"type": "global",
"hosting-title": "Monitor ROOT"
}"""
with open(os.path.join(self.private_dir, 'monitor.global.json')) as r:
result = json.loads(r.read().decode("utf-8"))
result.pop("date")
self.assertEquals(result,
json.loads(expected_result))
# all promises are OK now
self.writePromise('promise_2', success=True)
self.writePromise('promise_3', success=True)
promise_runner.runpromise()
globalstate.run([self.monitor_config_file, os.path.join(self.base_dir, 'instance.cfg')])
expected_result_dict = json.loads(expected_result)
expected_result_dict["status"] = "OK"
expected_result_dict["state"] = {'error': 0, 'success': 4}
with open(os.path.join(self.private_dir, 'monitor.global.json')) as r:
result = json.loads(r.read().decode("utf-8"))
result.pop("date")
self.assertEquals(result,
expected_result_dict)
This diff is collapsed.
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