Commit 95b0b149 authored by Swann Perarnau's avatar Swann Perarnau

Merge branch 'master' into 'code-cleanup-improvements'

# Conflicts:
#   nrm/containers.py
parents 3054b894 346eed43
...@@ -78,6 +78,46 @@ class CommandLineInterface(object): ...@@ -78,6 +78,46 @@ class CommandLineInterface(object):
logger.info("container response: %r", msg) logger.info("container response: %r", msg)
break break
def do_list(self, argv):
"""Connect to the NRM and ask to list the containers present on the
system.
The NRM should respond to us on the pub socket with one message listing
all containers."""
command = {'command': 'list',
}
while(True):
self.upstream_pub_socket.send_json(command)
msg = self.upstream_sub_socket.recv_json()
self.logger.info("new message: %r", msg)
# ignore other messages
if isinstance(msg, dict) and msg.get('type') == 'container':
if msg['event'] == 'list':
self.logger.info("list response: %r", msg)
break
def do_kill(self, argv):
"""Connect to the NRM and ask to kill a container by uuid.
The NRM should respond to us on the pub socket with a message
containing the exit status of the top process of the container."""
command = {'command': 'kill',
'uuid': argv.uuid
}
while(True):
self.upstream_pub_socket.send_json(command)
msg = self.upstream_sub_socket.recv_json()
self.logger.info("new message: %r", msg)
# ignore other messages
if isinstance(msg, dict) and msg.get('type') == 'container':
if msg['event'] == 'exit' and msg['uuid'] == argv.uuid:
self.logger.info("container exit: %r", msg)
break
def do_setpower(self, argv): def do_setpower(self, argv):
""" Connect to the NRM and ask to change the power limit. """ Connect to the NRM and ask to change the power limit.
...@@ -117,6 +157,15 @@ class CommandLineInterface(object): ...@@ -117,6 +157,15 @@ class CommandLineInterface(object):
nargs=argparse.REMAINDER) nargs=argparse.REMAINDER)
parser_run.set_defaults(func=self.do_run) parser_run.set_defaults(func=self.do_run)
# kill container
parser_kill = subparsers.add_parser("kill")
parser_kill.add_argument("uuid", help="uuid of the container")
parser_kill.set_defaults(func=self.do_kill)
# list containers
parser_list = subparsers.add_parser("list")
parser_list.set_defaults(func=self.do_list)
# setpowerlimit # setpowerlimit
parser_setpower = subparsers.add_parser("setpower") parser_setpower = subparsers.add_parser("setpower")
parser_setpower.add_argument("-f", "--follow", parser_setpower.add_argument("-f", "--follow",
...@@ -126,6 +175,7 @@ class CommandLineInterface(object): ...@@ -126,6 +175,7 @@ class CommandLineInterface(object):
help="set new power limit", help="set new power limit",
type=float) type=float)
parser_setpower.set_defaults(func=self.do_setpower) parser_setpower.set_defaults(func=self.do_setpower)
args = parser.parse_args() args = parser.parse_args()
if args.verbose: if args.verbose:
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
......
...@@ -4,6 +4,7 @@ from aci import ImageManifest ...@@ -4,6 +4,7 @@ from aci import ImageManifest
from collections import namedtuple from collections import namedtuple
import logging import logging
import os import os
import signal
from subprograms import ChrtClient, NodeOSClient, resources from subprograms import ChrtClient, NodeOSClient, resources
import sys import sys
...@@ -93,3 +94,19 @@ class ContainerManager(object): ...@@ -93,3 +94,19 @@ class ContainerManager(object):
c = self.containers[uuid] c = self.containers[uuid]
del self.containers[uuid] del self.containers[uuid]
del self.pids[c.pid] del self.pids[c.pid]
def kill(self, uuid):
"""Kill all the processes of a container."""
if uuid in self.containers:
c = self.containers[uuid]
self.logger.debug("killing %r:", c)
try:
os.kill(c.pid, signal.SIGKILL)
except OSError:
pass
def list(self):
"""List the containers in the system."""
fields = ['uuid', 'pid']
ret = [c._asdict() for c in self.containers.values()]
return [{k: d[k] for k in fields} for d in ret]
...@@ -124,6 +124,7 @@ class Daemon(object): ...@@ -124,6 +124,7 @@ class Daemon(object):
self.containerpids[pid] = msg['uuid'] self.containerpids[pid] = msg['uuid']
# TODO: obviously we need to send more info than that # TODO: obviously we need to send more info than that
update = {'type': 'container', update = {'type': 'container',
'event': 'start',
'uuid': msg['uuid'], 'uuid': msg['uuid'],
'errno': 0, 'errno': 0,
'pid': pid, 'pid': pid,
...@@ -131,10 +132,23 @@ class Daemon(object): ...@@ -131,10 +132,23 @@ class Daemon(object):
self.upstream_pub.send_json(update) self.upstream_pub.send_json(update)
else: else:
update = {'type': 'container', update = {'type': 'container',
'event': 'start',
'uuid': msg['uuid'], 'uuid': msg['uuid'],
'errno': pid, 'errno': pid,
} }
self.upstream_pub.send_json(update) self.upstream_pub.send_json(update)
elif command == 'kill':
self.logger.info("asked to kill container: %r", msg)
response = self.container_manager.kill(msg['uuid'])
# no update here, as it will trigger child exit
elif command == 'list':
self.logger.info("asked for container list: %r", msg)
response = self.container_manager.list()
update = {'type': 'container',
'event': 'list',
'payload': response,
}
self.upstream_pub.send_json(update)
else: else:
logger.error("invalid command: %r", command) logger.error("invalid command: %r", command)
...@@ -187,13 +201,13 @@ class Daemon(object): ...@@ -187,13 +201,13 @@ class Daemon(object):
# check if its a pid we care about # check if its a pid we care about
if pid in self.containerpids: if pid in self.containerpids:
# check if this is an exit # check if this is an exit
if os.WIFEXITED(status): if os.WIFEXITED(status) or os.WIFSIGNALED(status):
uuid = self.containerpids[pid] uuid = self.containerpids[pid]
self.container_manager.delete(uuid) self.container_manager.delete(uuid)
msg = {'type': 'container', msg = {'type': 'container',
'event': 'exit', 'event': 'exit',
'status': status, 'status': status,
'uuid': None, 'uuid': uuid,
} }
self.upstream_pub.send_json(msg) self.upstream_pub.send_json(msg)
else: else:
......
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