-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[sonic-host-service]: Add SONiC Host Services infrastructure #4840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ endif | |
| $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry | ||
| $(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t | ||
| $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro | ||
| $(DOCKER_TELEMETRY)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw | ||
nirenjan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" | ||
|
|
||
| $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
|
|
||
| SPATH := $($(SONIC_HOST_SERVICE)_SRC_PATH) | ||
| DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-service.mk rules/sonic-host-service.dep | ||
| SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) | ||
|
|
||
| $(SONIC_HOST_SERVICE)_CACHE_MODE := GIT_CONTENT_SHA | ||
| $(SONIC_HOST_SERVICE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) | ||
| $(SONIC_HOST_SERVICE)_DEP_FILES := $(DEP_FILES) | ||
| $(SONIC_HOST_SERVICE)_SMDEP_FILES := $(SMDEP_FILES) | ||
| $(SONIC_HOST_SERVICE)_SMDEP_PATHS := $(SPATH) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # SONiC host service package | ||
|
|
||
| ifeq ($(INCLUDE_HOST_SERVICE), y) | ||
|
|
||
| SONIC_HOST_SERVICE = sonic-host-service_1.0.0_all.deb | ||
| $(SONIC_HOST_SERVICE)_SRC_PATH = $(SRC_PATH)/sonic-host-service | ||
| SONIC_MAKE_DEBS += $(SONIC_HOST_SERVICE) | ||
|
|
||
| endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| ################################################################################ | ||
| # # | ||
| # Copyright 2020 Dell Inc. # | ||
| # # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); # | ||
| # you may not use this file except in compliance with the License. # | ||
| # You may obtain a copy of the License at # | ||
| # # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 # | ||
| # # | ||
| # Unless required by applicable law or agreed to in writing, software # | ||
| # distributed under the License is distributed on an "AS IS" BASIS, # | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # | ||
| # See the License for the specific language governing permissions and # | ||
| # limitations under the License. # | ||
| # # | ||
| ################################################################################ | ||
|
|
||
| TOPDIR := $(abspath .) | ||
| MAIN_TARGET = sonic-host-service_1.0.0_all.deb | ||
| INSTALL := /usr/bin/install | ||
|
|
||
| $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : | ||
| dpkg-buildpackage -us -uc -b | ||
| mv ../$(MAIN_TARGET) $(DEST)/ | ||
|
|
||
| SOURCES := $(wildcard '*.*') $(wildcard 'host_modules/*.py') | ||
| install: $(SOURCES) | ||
| # Scripts for host service | ||
| $(INSTALL) -d $(DESTDIR)/usr/lib/sonic_host_service/host_modules | ||
| $(INSTALL) -D $(TOPDIR)/sonic_host_server.py $(DESTDIR)/usr/lib/sonic_host_service | ||
| $(INSTALL) -D $(TOPDIR)/host_modules/*.py $(DESTDIR)/usr/lib/sonic_host_service/host_modules | ||
|
|
||
| # D-Bus permissions configuration | ||
| $(INSTALL) -d $(DESTDIR)/etc/dbus-1/system.d | ||
| $(INSTALL) -D $(TOPDIR)/org.sonic.hostservice.conf $(DESTDIR)/etc/dbus-1/system.d | ||
|
|
||
| # systemd unit | ||
| $(INSTALL) -d $(DESTDIR)/lib/systemd/system | ||
| $(INSTALL) -D $(TOPDIR)/sonic-hostservice.service $(DESTDIR)/lib/systemd/system | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| .debhelper | ||
| sonic-host-service.* | ||
| sonic-host-service/ | ||
| files |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| sonic-host-service (1.0.0) UNRELEASED; urgency=low | ||
|
|
||
| * Initial release. | ||
|
|
||
| -- Nirenjan Krishnan <Nirenjan.Krishnan@dell.com> Mon, 22 Jun 2020 00:00:00 +0000 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 9 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| Source: sonic-host-service | ||
| Maintainer: Nirenjan Krishnan <Nirenjan.Krishnan@dell.com> | ||
| Build-Depends: debhelper (>= 8.0.0), | ||
| dh-systemd | ||
| Vcs-Git: https://github.com/Azure/sonic-buildimage | ||
| Homepage: https://github.com/Azure/SONiC/ | ||
| Standards-Version: 3.9.3 | ||
| Section: net | ||
|
|
||
| Package: sonic-host-service | ||
| Priority: extra | ||
| Architecture: all | ||
| Depends: python3-systemd, python3-dbus, python3-gi, ${misc:Depends} | ||
| Description: SONiC Host Service | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #!/usr/bin/make -f | ||
| %: | ||
| dh $@ --with systemd --parallel | ||
|
|
||
| override_dh_auto_clean: | ||
| override_dh_auto_test: | ||
| override_dh_auto_build: | ||
| override_dh_auto_install: | ||
| make install DESTDIR=debian/sonic-host-service |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| """Base class for host modules""" | ||
|
|
||
| import dbus.service | ||
| import dbus | ||
|
|
||
| BUS_NAME_BASE = 'org.SONiC.HostService' | ||
| BUS_PATH = '/org/SONiC/HostService' | ||
|
|
||
| def bus_name(mod_name): | ||
| """Return the bus name for the service""" | ||
| return BUS_NAME_BASE + '.' + mod_name | ||
|
|
||
| def bus_path(mod_name): | ||
| """Return the bus path for the service""" | ||
| return BUS_PATH + '/' + mod_name | ||
|
|
||
| method = dbus.service.method | ||
|
|
||
| class HostService(dbus.service.Object): | ||
| """Service class for top level DBus endpoint""" | ||
| def __init__(self, mod_name): | ||
| self.bus = dbus.SystemBus() | ||
| self.bus_name = dbus.service.BusName(BUS_NAME_BASE, self.bus) | ||
| super(HostService, self).__init__(self.bus_name, BUS_PATH) | ||
|
|
||
| class HostModule(dbus.service.Object): | ||
| """Base class for all host modules""" | ||
| def __init__(self, mod_name): | ||
| self.bus = dbus.SystemBus() | ||
| self.bus_name = dbus.service.BusName(bus_name(mod_name), self.bus) | ||
| super(HostModule, self).__init__(self.bus_name, bus_path(mod_name)) | ||
|
|
||
| def register(): | ||
| return HostService, "host_service" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <!DOCTYPE busconfig PUBLIC | ||
| "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" | ||
| "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> | ||
| <busconfig> | ||
|
|
||
| <!-- Only root can own the bus --> | ||
|
|
||
| <policy user="root"> | ||
| <allow own_prefix="org.SONiC.HostService"/> | ||
renukamanavalan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| </policy> | ||
|
|
||
| <!-- Allow user "root" to invoke methods on the bus --> | ||
renukamanavalan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| <policy user="root"> | ||
| <allow send_destination="org.SONiC.HostService"/> | ||
| <allow receive_sender="org.SONiC.HostService"/> | ||
| </policy> | ||
|
|
||
| </busconfig> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| [Unit] | ||
| Description=SONiC Host Service | ||
|
|
||
| [Service] | ||
| Type=dbus | ||
| BusName=org.SONiC.HostService | ||
|
|
||
| ExecStart=/usr/bin/python3 -u /usr/lib/sonic_host_service/sonic_host_server.py | ||
|
|
||
| Restart=on-failure | ||
| RestartSec=10 | ||
| TimeoutStopSec=3 | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| #!/usr/bin/env python3 | ||
| """Host Service to handle docker-to-host communication""" | ||
|
|
||
| import os | ||
| import os.path | ||
| import glob | ||
| import importlib | ||
| import sys | ||
|
|
||
| import dbus | ||
| import dbus.service | ||
| import dbus.mainloop.glib | ||
|
|
||
| from gi.repository import GObject | ||
|
|
||
| def register_modules(): | ||
renukamanavalan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """Register all host modules""" | ||
| mod_path = os.path.join(os.path.dirname(__file__), 'host_modules') | ||
| sys.path.append(mod_path) | ||
| for mod_file in glob.glob(os.path.join(mod_path, '*.py')): | ||
| if os.path.isfile(mod_file) and not mod_file.endswith('__init__.py'): | ||
| mod_name = os.path.basename(mod_file)[:-3] | ||
| module = importlib.import_module(mod_name) | ||
|
|
||
| register_cb = getattr(module, 'register', None) | ||
| if not register_cb: | ||
| raise Exception('Missing register function for ' + mod_name) | ||
renukamanavalan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| register_dbus(register_cb) | ||
|
|
||
| def register_dbus(register_cb): | ||
| """Register DBus handlers for individual modules""" | ||
| handler_class, mod_name = register_cb() | ||
| handlers[mod_name] = handler_class(mod_name) | ||
|
|
||
| # Create a main loop reactor | ||
| GObject.threads_init() | ||
| dbus.mainloop.glib.threads_init() | ||
| dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | ||
| loop = GObject.MainLoop() | ||
| handlers = {} | ||
|
|
||
| class SignalManager(object): | ||
| ''' This is used to manage signals received (e.g. SIGINT). | ||
| When stopping a process (systemctl stop [service]), systemd sends | ||
| a SIGTERM signal. | ||
| ''' | ||
| shutdown = False | ||
| def __init__(self): | ||
| ''' Install signal handlers. | ||
|
|
||
| SIGTERM is invoked when systemd wants to stop the daemon. | ||
| For example, "systemctl stop mydaemon.service" | ||
| or, "systemctl restart mydaemon.service" | ||
|
|
||
| ''' | ||
| import signal | ||
| signal.signal(signal.SIGTERM, self.sigterm_hdlr) | ||
|
|
||
| def sigterm_hdlr(self, _signum, _frame): | ||
| self.shutdown = True | ||
| loop.quit() | ||
|
|
||
| sigmgr = SignalManager() | ||
| register_modules() | ||
|
|
||
| # Only run if we actually have some handlers | ||
| if handlers: | ||
| import systemd.daemon | ||
| systemd.daemon.notify("READY=1") | ||
|
|
||
| while not sigmgr.shutdown: | ||
| loop.run() | ||
| if sigmgr.shutdown: | ||
| break | ||
|
|
||
| systemd.daemon.notify("STOPPING=1") | ||
| else: | ||
| print("No handlers to register, quitting...") | ||
renukamanavalan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.