diff options
author | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-05-16 23:53:40 -0500 |
---|---|---|
committer | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-05-26 00:17:00 -0500 |
commit | 5de0957ccc5ba51bba375d2434cd3420b7a2c3af (patch) | |
tree | eb3cd0cd22ff0695497362241b3b8da70ed2dd00 | |
parent | 3b8d055ca761a68c74dad01a306f238674d71878 (diff) | |
download | phosphor-settingsd-5de0957ccc5ba51bba375d2434cd3420b7a2c3af.tar.gz phosphor-settingsd-5de0957ccc5ba51bba375d2434cd3420b7a2c3af.zip |
Add settings application
Implement settings d-bus interfaces.
Define a settings policy file (this commit checks in an example YAML
based policy), based on which code for a settings manager will be
generated via a python script.
This settings manager composes and places desired settings objects on
the bus.
The policy file can be supplied by a system specific bitbake recipe.
Resolves openbmc/openbmc#1487.
Change-Id: Ice0d3b319d9466824cef323a6915eb20ca5cae5c
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
-rwxr-xr-x | Makefile.am | 33 | ||||
-rwxr-xr-x | bootstrap.sh | 18 | ||||
-rw-r--r-- | configure.ac | 42 | ||||
-rwxr-xr-x | settings.py | 31 | ||||
-rw-r--r-- | settings_example.yaml | 9 | ||||
-rw-r--r-- | settings_main.cpp | 24 | ||||
-rw-r--r-- | settings_manager.mako.hpp | 105 |
7 files changed, 262 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 0000000..65f95cb --- /dev/null +++ b/Makefile.am @@ -0,0 +1,33 @@ +AM_DEFAULT_SOURCE_EXT = .cpp + +BUILT_SOURCES = \ + settings_manager.hpp +CLEANFILES = \ + settings_manager.hpp + +SETTINGS_GEN_SCRIPT ?= \ + ${abs_srcdir}/settings.py +SETTINGS_GEN_SCRIPT_FILES ?= \ + ${abs_srcdir}/settings_example.yaml \ + ${abs_srcdir}/settings_manager.mako.hpp + +settings_manager.hpp: ${SETTINGS_GEN_SCRIPT} ${SETTINGS_GEN_SCRIPT_FILES} + $(AM_V_GEN)@SETTINGSGEN@ + +# Build these headers, don't install them +noinst_HEADERS = \ + settings_manager.hpp + +sbin_PROGRAMS = \ + phosphor-settings-manager + +phosphor_settings_manager_SOURCES = \ + settings_main.cpp + +phosphor_settings_manager_CXXFLAGS = \ + $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \ + $(SDBUSPLUS_CFLAGS) + +phosphor_settings_manager_LDADD = \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ + $(SDBUSPLUS_LIBS) diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..f861496 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,18 @@ +#!/bin/sh -xe + +AUTOCONF_FILES="Makefile.in aclocal.m4 ar-lib autom4te.cache compile \ + config.guess config.h.in config.sub configure depcomp install-sh \ + ltmain.sh missing *libtool test-driver" + +case $1 in + clean) + test -f Makefile && make maintainer-clean + for file in ${AUTOCONF_FILES}; do + find -name "$file" | xargs -r rm -rf + done + exit 0 + ;; +esac + +autoreconf -i +echo 'Run "./configure ${CONFIGURE_FLAGS} && make"' diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..6b3191d --- /dev/null +++ b/configure.ac @@ -0,0 +1,42 @@ +AC_PREREQ([2.69]) +AC_INIT([phosphor-settingsd], [1.0], [https://github.com/openbmc/phosphor-settingsd/issues]) +AC_LANG([C++]) +AC_CONFIG_HEADERS([config.h]) +AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign dist-xz]) +AM_SILENT_RULES([yes]) + +AC_PROG_CXX +AM_PROG_AR +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AM_PATH_PYTHON([2.7], [AC_SUBST([PYTHON], [echo "$PYTHON"])], [AC_MSG_ERROR( + [Could not find python-2.7 installed...python-2.7 is required])]) + +PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],,\ + AC_MSG_ERROR(["Requires phosphor-dbus-interfaces package."])) +PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],, + AC_MSG_ERROR(["Requires sdbusplus package."])) + +LT_INIT + +AX_CXX_COMPILE_STDCXX_14([noext]) +AX_APPEND_COMPILE_FLAGS([-Wall -Werror], [CXXFLAGS]) + +AC_ARG_VAR(SETTINGS_BUSNAME, [The Dbus busname to own]) +AS_IF([test "x$SETTINGS_BUSNAME" == "x"],\ + [SETTINGS_BUSNAME="xyz.openbmc_project.Settings"]) +AC_DEFINE_UNQUOTED([SETTINGS_BUSNAME], ["$SETTINGS_BUSNAME"],\ + [The DBus busname to own]) + +AC_ARG_VAR(SETTINGS_ROOT, [The settings Dbus root]) +AS_IF([test "x$SETTINGS_ROOT" == "x"],\ + [SETTINGS_ROOT="/xyz/openbmc_project/settings"]) +AC_DEFINE_UNQUOTED([SETTINGS_ROOT], ["$SETTINGS_ROOT"],\ + [The settings Dbus root]) + +AS_IF([test "x$SETTINGS_YAML" == "x"], [SETTINGS_YAML="settings_example.yaml"]) +SETTINGSGEN="$PYTHON $srcdir/settings.py -i $SETTINGS_YAML" +AC_SUBST(SETTINGSGEN) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/settings.py b/settings.py new file mode 100755 index 0000000..adee094 --- /dev/null +++ b/settings.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +import os +import yaml +from mako.template import Template +import argparse + +def main(): + parser = argparse.ArgumentParser( + description="Settings YAML parser and code generator") + + parser.add_argument( + '-i', '--settings_yaml', dest='settings_yaml', + default='settings_example.yaml', help='settings yaml file to parse') + args = parser.parse_args() + + with open(os.path.join(script_dir, args.settings_yaml), 'r') as fd: + yamlDict = yaml.safe_load(fd) + + # Render the mako template + template = os.path.join(script_dir, 'settings_manager.mako.hpp') + t = Template(filename=template) + with open('settings_manager.hpp', 'w') as fd: + fd.write( + t.render( + settingsDict=yamlDict)) + + +if __name__ == '__main__': + script_dir = os.path.dirname(os.path.realpath(__file__)) + main() diff --git a/settings_example.yaml b/settings_example.yaml new file mode 100644 index 0000000..d6e7f88 --- /dev/null +++ b/settings_example.yaml @@ -0,0 +1,9 @@ +/xyz/openbmc_project/control/host0/boot_mode: + Interface: xyz.openbmc_project.Control.Boot.Mode + Defaults: + BootMode: Mode::Modes::Safe + +/xyz/openbmc_project/control/host1/boot_mode: + Interface: xyz.openbmc_project.Control.Boot.Mode + Defaults: + BootMode: Mode::Modes::Regular diff --git a/settings_main.cpp b/settings_main.cpp new file mode 100644 index 0000000..22d6146 --- /dev/null +++ b/settings_main.cpp @@ -0,0 +1,24 @@ +#include <sdbusplus/bus.hpp> +#include <sdbusplus/server/manager.hpp> +#include "settings_manager.hpp" +#include "config.h" + +int main(int argc, char *argv[]) +{ + auto bus = sdbusplus::bus::new_default(); + + // Add sdbusplus ObjectManager for the settings root. + sdbusplus::server::manager::manager objManager(bus, SETTINGS_ROOT); + + phosphor::settings::Manager mgr(bus); + + bus.request_name(SETTINGS_BUSNAME); + + while(true) + { + bus.process_discard(); + bus.wait(); + } + + return 0; +} diff --git a/settings_manager.mako.hpp b/settings_manager.mako.hpp new file mode 100644 index 0000000..2f97985 --- /dev/null +++ b/settings_manager.mako.hpp @@ -0,0 +1,105 @@ +## This file is a template. The comment below is emitted +## into the rendered file; feel free to edit this file. +// WARNING: Generated header. Do not edit! + +<% +objects = list(settingsDict.viewkeys()) + +def get_setting_type(setting_intf): + setting = "sdbusplus::" + setting_intf.replace('.', '::') + i = setting.rfind('::') + setting = setting[:i] + '::server::' + setting[i+2:] + return setting +%>\ +#pragma once + +% for object in objects: +<% + includes = [] + include = settingsDict[object]['Interface'] + include = include.replace('.', '/') + include = include + "/server.hpp" + includes.append(include) +%>\ +% endfor +% for i in set(includes): +#include "${i}" +% endfor + +% for object in objects: +<% + ns_list = [] + ns = get_setting_type(settingsDict[object]['Interface']) + i = ns.rfind('::') + ns = ns[:i] + ns_list.append(ns) +%>\ +% endfor +% for n in set(ns_list): +using namespace ${n}; +% endfor + +namespace phosphor +{ +namespace settings +{ + +/** @class Manager + * + * @brief Compose settings objects and put them on the bus. + */ +class Manager +{ + public: + Manager() = delete; + Manager(const Manager&) = delete; + Manager& operator=(const Manager&) = delete; + Manager(Manager&&) = delete; + Manager& operator=(Manager&&) = delete; + virtual ~Manager() = default; + + /** @brief Constructor to put settings objects on to the bus. + * @param[in] bus - Bus to attach to. + */ + Manager(sdbusplus::bus::bus& bus) + { + settings = + std::make_tuple( +% for index, object in enumerate(objects): +<% type = get_setting_type(settingsDict[object]['Interface']) %>\ + std::make_unique<${type}>( + bus, + % if index < len(settingsDict) - 1: + "${object}"), + % else: + "${object}")); + % endif +% endfor + +% for index, object in enumerate(objects): + % if 'Defaults' in settingsDict[object].viewkeys(): + % for property, value in settingsDict[object]['Defaults'].items(): + std::get<${index}>(settings)-> + setPropertyByName("${property}", ${value}); + % endfor + % endif + bus.emit_object_added("${object}"); + +% endfor + } + + private: + /* @brief Composition of settings objects. */ + std::tuple< +% for index, object in enumerate(objects): +<% type = get_setting_type(settingsDict[object]['Interface']) %>\ + % if index < len(settingsDict) - 1: + std::unique_ptr<${type}>, + % else: + std::unique_ptr<${type}>> settings; + % endif +% endfor +}; + +} // namespace settings +} // namespace phosphor |