Skip to content

Commit

Permalink
Adjust nodemgr for Windows
Browse files Browse the repository at this point in the history
Where convenient I've implemented some level of indirection,
where inconvenient I've used platform checking to skip some
Linux only code. Real code checking running processes and so
on will be submitted in next changes.

Change-Id: I5abb1b37621c295eac56ff096c5a348f999588c9
Partial-Bug: #1783539
  • Loading branch information
Michal Clapinski committed Jul 26, 2018
1 parent d9d8fdf commit 1af9785
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 38 deletions.
5 changes: 4 additions & 1 deletion src/nodemgr/SConscript
Expand Up @@ -85,9 +85,12 @@ common_sources = [
'common/docker_mem_cpu.py',
'common/docker_process_manager.py',
'common/event_manager.py',
'common/linux_sys_mem_cpu.py',
'common/process_stat.py',
'common/sys_mem_cpu.py',
'common/utils.py',
'common/windows_process_manager.py',
'common/windows_process_mem_cpu.py',
'common/windows_sys_mem_cpu.py',
]
common_sources_rules = []
for file in common_sources:
Expand Down
2 changes: 1 addition & 1 deletion src/nodemgr/common/docker_process_manager.py
Expand Up @@ -216,7 +216,7 @@ def get_all_processes(self):
return processes_info_list

def runforever(self):
# TODO: probaly use subscription on events..
# TODO: probably use subscription on events..
while True:
self._poll_containers()
gevent.sleep(seconds=5)
Expand Down
73 changes: 49 additions & 24 deletions src/nodemgr/common/event_manager.py
Expand Up @@ -8,6 +8,7 @@
import os
import socket
import time
import platform
import subprocess
from subprocess import Popen, PIPE
import random
Expand All @@ -16,8 +17,6 @@

from buildinfo import build_info

from sys_mem_cpu import SysMemCpuUsageData

from process_stat import ProcessStat

from sandesh.nodeinfo.ttypes import *
Expand All @@ -44,6 +43,12 @@

import utils

if platform.system() == 'Windows':
from windows_sys_mem_cpu import WindowsSysMemCpuUsageData as SysMemCpuUsageData
from windows_process_manager import WindowsProcessInfoManager
else:
from linux_sys_mem_cpu import LinuxSysMemCpuUsageData as SysMemCpuUsageData


class EventManagerTypeInfo(object):
def __init__(self, module_type, object_table, sandesh_packages=[]):
Expand Down Expand Up @@ -115,7 +120,9 @@ def __init__(self, config, type_info, sandesh_instance,
syslog_facility=self.config.syslog_facility)
self.logger = self.sandesh_instance.logger()

if DockerProcessInfoManager and (utils.is_running_in_docker()
if platform.system() == 'Windows':
self.process_info_manager = WindowsProcessInfoManager()
elif DockerProcessInfoManager and (utils.is_running_in_docker()
or utils.is_running_in_kubepod()):
self.process_info_manager = DockerProcessInfoManager(
type_info._module_type, unit_names, event_handlers,
Expand Down Expand Up @@ -215,31 +222,37 @@ def get_process_state_cb(self):
return state, description

def check_ntp_status(self):
ntp_status_cmd = 'ntpq -n -c pe | grep "^*"'
proc = Popen(ntp_status_cmd, shell=True, stdout=PIPE, stderr=PIPE,
close_fds=True)
(_, _) = proc.communicate()
if proc.returncode != 0:
self.fail_status_bits |= self.FAIL_STATUS_NTP_SYNC
else:
self.fail_status_bits &= ~self.FAIL_STATUS_NTP_SYNC
if platform.system() != 'Windows':
ntp_status_cmd = 'ntpq -n -c pe | grep "^*"'
proc = Popen(ntp_status_cmd, shell=True, stdout=PIPE, stderr=PIPE,
close_fds=True)
(_, _) = proc.communicate()
if proc.returncode != 0:
self.fail_status_bits |= self.FAIL_STATUS_NTP_SYNC
else:
self.fail_status_bits &= ~self.FAIL_STATUS_NTP_SYNC
self.send_nodemgr_process_status()

def get_build_info(self):
# Retrieve build_info from package/rpm and cache it
if self.curr_build_info is not None:
return self.curr_build_info

command = "contrail-version contrail-nodemgr | grep contrail-nodemgr"
version = os.popen(command).read()
version_partials = version.split()
if len(version_partials) < 3:
self.msg_log('Not enough values to parse package version %s'
% version,
SandeshLevel.SYS_ERR)
return ""
if platform.system() == 'Windows':
rpm_version = ""
build_num = "unknown"
else:
_, rpm_version, build_num = version_partials
# Retrieve build_info from package/rpm and cache it
if self.curr_build_info is not None:
return self.curr_build_info

command = "contrail-version contrail-nodemgr | grep contrail-nodemgr"
version = os.popen(command).read()
version_partials = version.split()
if len(version_partials) < 3:
self.msg_log('Not enough values to parse package version %s'
% version,
SandeshLevel.SYS_ERR)
return ""
else:
_, rpm_version, build_num = version_partials

self.new_build_info = build_info + '"build-id" : "' + \
rpm_version + '", "build-number" : "' + \
build_num + '"}]}'
Expand All @@ -248,6 +261,9 @@ def get_build_info(self):
return self.curr_build_info

def get_corefile_path(self):
if platform.system() == 'Windows':
return ""

self.core_file_path = self.config.corefile_path
cat_command = "cat /proc/sys/kernel/core_pattern"
(core_pattern, _) = Popen(
Expand All @@ -261,6 +277,9 @@ def get_corefile_path(self):
return self.core_file_path.rstrip()

def get_corefiles(self):
if platform.system() == 'Windows':
return []

try:
# Get the core files list in the chronological order
ls_command = "ls -1tr " + self.get_corefile_path()
Expand Down Expand Up @@ -354,6 +373,9 @@ def send_process_state_db(self, group_names):
# end send_process_state_db

def update_all_core_file(self):
if platform.system() == 'Windows':
return False

stat_command_option = "stat --printf=%Y " + self.get_corefile_path()
modified_time = Popen(
stat_command_option.split(),
Expand Down Expand Up @@ -529,6 +551,9 @@ def get_group_processes_mem_cpu_usage(self, group_name):

def get_disk_usage(self):
disk_usage_info = {}
if platform.system() == 'Windows':
return disk_usage_info

partition = subprocess.Popen(
"df -PT -t ext2 -t ext3 -t ext4 -t xfs",
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
Expand Down
Expand Up @@ -14,7 +14,7 @@ def _run_cmd(cmd):
return int(proc.communicate()[0])


class SysMemCpuUsageData(object):
class LinuxSysMemCpuUsageData(object):
def __init__(self, last_cpu, last_time):
self.last_cpu = last_cpu
self.last_time = last_time
Expand Down
18 changes: 18 additions & 0 deletions src/nodemgr/common/windows_process_manager.py
@@ -0,0 +1,18 @@
#
# Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
#

import time

from windows_process_mem_cpu import WindowsProcessMemCpuUsageData

class WindowsProcessInfoManager(object):
def get_mem_cpu_usage_data(self, pid, last_cpu, last_time):
return WindowsProcessMemCpuUsageData(pid, last_cpu, last_time)

def get_all_processes(self):
return []

def runforever(self):
while True:
time.sleep(5)
15 changes: 15 additions & 0 deletions src/nodemgr/common/windows_process_mem_cpu.py
@@ -0,0 +1,15 @@
#
# Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
#

from sandesh.nodeinfo.cpuinfo.ttypes import ProcessCpuInfo

class WindowsProcessMemCpuUsageData(object):
def __init__(self, _id, last_cpu, last_time):
self.last_cpu = last_cpu
self.last_time = last_time
self._id = hex(_id)[2:-1].zfill(64)

def get_process_mem_cpu_info(self):
process_mem_cpu = ProcessCpuInfo()
return process_mem_cpu
30 changes: 30 additions & 0 deletions src/nodemgr/common/windows_sys_mem_cpu.py
@@ -0,0 +1,30 @@
#
# Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
#

from sandesh.nodeinfo.cpuinfo.ttypes import SysMemInfo, SysCpuInfo

class WindowsSysMemCpuUsageData(object):
def __init__(self, last_cpu, last_time):
self.last_cpu = last_cpu
self.last_time = last_time

def get_num_socket(self):
return 0

def get_num_cpu(self):
return 0

def get_num_core_per_socket(self):
return 0

def get_num_thread_per_core(self):
return 0

def get_sys_mem_info(self, node_type):
sys_mem_info = SysMemInfo()
return sys_mem_info

def get_sys_cpu_info(self, node_type):
sys_cpu_info = SysCpuInfo()
return sys_cpu_info
31 changes: 20 additions & 11 deletions src/nodemgr/main.py
Expand Up @@ -41,6 +41,7 @@
import hashlib
import random
import os
import platform
import signal
import sys

Expand Down Expand Up @@ -130,20 +131,27 @@ def main(args_str=' '.join(sys.argv[1:])):
default.update(SandeshConfig.get_default_options(['DEFAULTS']))
sandesh_opts = SandeshConfig.get_default_options()
node_type = args.nodetype

if platform.system() == 'Windows':
path_prefix = os.environ['ProgramData'] + '/Contrail'
else:
path_prefix = ""

config_file = path_prefix
if (node_type == 'contrail-analytics'):
config_file = '/etc/contrail/contrail-analytics-nodemgr.conf'
config_file += '/etc/contrail/contrail-analytics-nodemgr.conf'
elif (node_type == 'contrail-config'):
config_file = '/etc/contrail/contrail-config-nodemgr.conf'
config_file += '/etc/contrail/contrail-config-nodemgr.conf'
elif (node_type == 'contrail-config-database'):
config_file = '/etc/contrail/contrail-config-database-nodemgr.conf'
config_file += '/etc/contrail/contrail-config-database-nodemgr.conf'
elif (node_type == 'contrail-control'):
config_file = '/etc/contrail/contrail-control-nodemgr.conf'
config_file += '/etc/contrail/contrail-control-nodemgr.conf'
elif (node_type == 'contrail-vrouter'):
config_file = '/etc/contrail/contrail-vrouter-nodemgr.conf'
config_file += '/etc/contrail/contrail-vrouter-nodemgr.conf'
elif (node_type == 'contrail-database'):
config_file = '/etc/contrail/contrail-database-nodemgr.conf'
config_file += '/etc/contrail/contrail-database-nodemgr.conf'
else:
sys.stderr.write("Node type" + str(node_type) + "is incorrect\n")
sys.stderr.write("Node type" + str(node_type) + " is incorrect\n")
return
if (os.path.exists(config_file) == False):
sys.stderr.write("config file " + config_file + " is not present\n")
Expand Down Expand Up @@ -245,10 +253,11 @@ def main(args_str=' '.join(sys.argv[1:])):
prog.collector_chksum = _args.chksum
prog.random_collectors = _args.random_collectors

""" @sighup
Reconfig of collector list
"""
gevent.signal(signal.SIGHUP, prog.nodemgr_sighup_handler)
if platform.system() != 'Windows':
""" @sighup
Reconfig of collector list
"""
gevent.signal(signal.SIGHUP, prog.nodemgr_sighup_handler)

gevent.joinall([gevent.spawn(prog.runforever),
gevent.spawn(prog.run_periodically(prog.do_periodic_events, 60))])
Expand Down

0 comments on commit 1af9785

Please sign in to comment.