Fix persistence of dynamically created zones 30/33630/6
authorPiotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
Tue, 13 Jan 2015 10:25:52 +0000 (11:25 +0100)
committerJan Olszak <j.olszak@samsung.com>
Thu, 15 Jan 2015 15:45:47 +0000 (07:45 -0800)
[Bug]           No zones after daemon restart
[Cause]         N/A
[Solution]      Use database to store dynamic config
[Verification]  1) run tests
                2) - run daemon
                   - create new zone
                   - restart daemon, verify zone is working
                   - destroy that zone
                   - restart daemon, verify zone is gone

Change-Id: I43f3e2f4f2d9c897d20b52db812dd837c90ef155

22 files changed:
packaging/vasum.spec
server/configs/CMakeLists.txt
server/configs/daemon.conf.in
server/configs/zones/business.conf [deleted file]
server/configs/zones/private.conf [deleted file]
server/main.cpp
server/server.cpp
server/server.hpp
server/zones-manager-config.hpp
server/zones-manager.cpp
server/zones-manager.hpp
tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf.in
tests/unit_tests/server/configs/ut-server/buggy-daemon.conf.in
tests/unit_tests/server/configs/ut-server/test-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/buggy-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/empty-dbus-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/test-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/test-dbus-daemon.conf.in
tests/unit_tests/server/ut-server.cpp
tests/unit_tests/server/ut-zones-manager.cpp

index e743a75..113348b 100644 (file)
@@ -45,7 +45,6 @@ between them. A process from inside a zone can request a switch of context
 %dir /etc/vasum/lxc-templates
 %dir /etc/vasum/templates
 %config /etc/vasum/daemon.conf
-%config /etc/vasum/zones/*.conf
 %attr(755,root,root) /etc/vasum/lxc-templates/*.sh
 %config /etc/vasum/templates/*.conf
 %{_unitdir}/vasum.service
index 9c0fa4b..f5f82c5 100644 (file)
@@ -19,7 +19,6 @@
 
 MESSAGE(STATUS "Installing configs to " ${VSM_CONFIG_INSTALL_DIR})
 
-FILE(GLOB zone_CONF          zones/*.conf)
 FILE(GLOB admin_CONF         lxc-templates/*.sh)
 FILE(GLOB template_CONF      templates/*.conf)
 
@@ -42,8 +41,7 @@ CONFIGURE_FILE(dbus-1/system.d/org.tizen.vasum.host.conf.in
 INSTALL(FILES       ${CMAKE_BINARY_DIR}/dbus-1/system.d/org.tizen.vasum.host.conf
         DESTINATION ${SYSCONF_INSTALL_DIR}/dbus-1/system.d/)
 
-INSTALL(FILES       ${zone_CONF}
-        DESTINATION ${VSM_CONFIG_INSTALL_DIR}/zones)
+INSTALL(DIRECTORY   DESTINATION ${VSM_CONFIG_INSTALL_DIR}/zones) #TODO temporary solution
 
 INSTALL(PROGRAMS    ${admin_CONF}
         DESTINATION ${VSM_CONFIG_INSTALL_DIR}/lxc-templates)
index 4522bb5..b7d9c87 100644 (file)
@@ -1,12 +1,13 @@
 {
-    "zoneConfigs" : ["zones/private.conf", "zones/business.conf"],
+    "dbPath" : "/usr/dbspace/vasum.db",
+    "zoneConfigs" : [],
     "zonesPath" : "${DATA_DIR}/.zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
+    "zoneTemplatePath" : "/etc/vasum/templates/template.conf",
     "zoneNewConfigPrefix" : "/var/lib/vasum",
     "runMountPointPrefix" : "/var/run/zones",
-    "foregroundId" : "private",
-    "defaultId" : "private",
+    "foregroundId" : "",
+    "defaultId" : "",
     "lxcTemplatePrefix" : "/etc/vasum/lxc-templates",
     "inputConfig" : {"enabled" : true,
                      "device" : "gpio_keys.6",
diff --git a/server/configs/zones/business.conf b/server/configs/zones/business.conf
deleted file mode 100644 (file)
index 74c3bad..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "name" : "business",
-    "lxcTemplate" : "tizen-common-wayland.sh",
-    "initWithArgs" : [],
-    "ipv4Gateway" : "10.0.102.1",
-    "ipv4" : "10.0.102.2",
-    "cpuQuotaForeground" : -1,
-    "cpuQuotaBackground" : 10000,
-    "enableDbusIntegration" : true,
-    "privilege" : 1,
-    "vt" : 3,
-    "switchToDefaultAfterTimeout" : true,
-    "runMountPoint" : "business/run",
-    "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ],
-    "validLinkPrefixes" : [ "/tmp/",
-                            "/run/",
-                            "/opt/usr/data/",
-                            "/opt/usr/dbsapce/" ]
-}
diff --git a/server/configs/zones/private.conf b/server/configs/zones/private.conf
deleted file mode 100644 (file)
index ffb7e85..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "name" : "private",
-    "lxcTemplate" : "tizen-common-wayland.sh",
-    "initWithArgs" : [],
-    "ipv4Gateway" : "10.0.101.1",
-    "ipv4" : "10.0.101.2",
-    "cpuQuotaForeground" : -1,
-    "cpuQuotaBackground" : 10000,
-    "enableDbusIntegration" : true,
-    "privilege" : 10,
-    "vt" : 2,
-    "switchToDefaultAfterTimeout" : true,
-    "runMountPoint" : "private/run",
-    "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ],
-    "validLinkPrefixes" : [ "/tmp/",
-                            "/run/",
-                            "/opt/usr/data/",
-                            "/opt/usr/dbsapce/" ]
-}
index d641148..fb3eed4 100644 (file)
@@ -52,11 +52,13 @@ namespace {
 const std::string PROGRAM_NAME_AND_VERSION =
     "Vasum Server " PROGRAM_VERSION;
 
+const std::string CONFIG_PATH = "/etc/vasum/daemon.conf";
+
+
 } // namespace
 
 int main(int argc, char* argv[])
 {
-    std::string configPath;
     bool runAsRoot = false;
 
     try {
@@ -67,7 +69,6 @@ int main(int argc, char* argv[])
         ("root,r", "Don't drop root privileges at startup")
         ("version,v", "show application version")
         ("log-level,l", po::value<std::string>()->default_value("DEBUG"), "set log level")
-        ("config,c", po::value<std::string>()->default_value("/etc/vasum/daemon.conf"), "server configuration file")
         ;
 
         po::variables_map vm;
@@ -108,7 +109,6 @@ int main(int argc, char* argv[])
         Logger::setLogBackend(new SystemdJournalBackend());
 #endif
 
-        configPath = vm["config"].as<std::string>();
         runAsRoot = vm.count("root") > 0;
 
     } catch (std::exception& e) {
@@ -117,8 +117,8 @@ int main(int argc, char* argv[])
     }
 
     try {
-        Server server(configPath, runAsRoot);
-        server.run();
+        Server server(CONFIG_PATH);
+        server.run(runAsRoot);
         server.reloadIfRequired(argv);
 
     } catch (std::exception& e) {
index d9a1628..2f30a55 100644 (file)
@@ -67,17 +67,9 @@ extern char** environ;
 namespace vasum {
 
 
-Server::Server(const std::string& configPath, bool runAsRoot)
+Server::Server(const std::string& configPath)
     : mConfigPath(configPath)
 {
-    if (!prepareEnvironment(configPath, runAsRoot)) {
-        throw ServerException("Environment setup failed");
-    }
-}
-
-
-Server::~Server()
-{
 }
 
 
@@ -100,8 +92,12 @@ void signalHandler(const int sig)
 
 } // namespace
 
-void Server::run()
+void Server::run(bool asRoot)
 {
+    if (!prepareEnvironment(mConfigPath, asRoot)) {
+        throw ServerException("Environment setup failed");
+    }
+
     signal(SIGINT,  signalHandler);
     signal(SIGTERM, signalHandler);
     signal(SIGUSR1, signalHandler);
index 009a468..8bac0b0 100644 (file)
@@ -36,18 +36,12 @@ namespace vasum {
 
 class Server {
 public:
-    Server(const std::string& configPath, bool runAsRoot = true);
-    virtual ~Server();
-
-    /**
-     * Set needed caps, groups and drop root privileges.
-     */
-    static bool prepareEnvironment(const std::string& configPath, bool runAsRoot);
+    Server(const std::string& configPath);
 
     /**
      * Starts all the zones and blocks until SIGINT, SIGTERM or SIGUSR1
      */
-    void run();
+    void run(bool asRoot);
 
     /**
      * Reload the server by launching execve on itself if SIGUSR1 was sent to server.
@@ -59,8 +53,15 @@ public:
      * Equivalent of sending SIGINT or SIGTERM signal
      */
     void terminate();
+
 private:
     std::string mConfigPath;
+
+    /**
+     * Set needed caps, groups and drop root privileges.
+     */
+    static bool prepareEnvironment(const std::string& configPath, bool runAsRoot);
+
 };
 
 
index 1838d25..ab55762 100644 (file)
 
 namespace vasum {
 
-
-const std::string ZONES_MANAGER_CONFIG_PATH = "/etc/vasum/config/daemon.conf";
-
 struct ZonesManagerConfig {
 
     /**
-     * List of zones' configs that we manage.
-     * File paths can be relative to the ZoneManager config file.
+     * Path to config database.
      */
-    std::vector<std::string> zoneConfigs;
+    std::string dbPath;
 
     /**
      * An ID of a currently focused/foreground zone.
@@ -100,7 +96,7 @@ struct ZonesManagerConfig {
 
     CONFIG_REGISTER
     (
-        zoneConfigs,
+        dbPath,
         foregroundId,
         defaultId,
         zonesPath,
@@ -114,6 +110,19 @@ struct ZonesManagerConfig {
     )
 };
 
+struct ZonesManagerDynamicConfig {
+
+    /**
+     * List of zones' configs that we manage.
+     * File paths can be relative to the ZoneManager config file.
+     */
+    std::vector<std::string> zoneConfigs;
+
+    CONFIG_REGISTER
+    (
+        zoneConfigs
+    )
+};
 
 } // namespace vasum
 
index ff6fb7e..840d8c4 100644 (file)
@@ -75,15 +75,28 @@ const boost::regex ZONE_VT_REGEX("~VT~");
 const unsigned int ZONE_IP_BASE_THIRD_OCTET = 100;
 const unsigned int ZONE_VT_BASE = 1;
 
+std::string getConfigName(const std::string& zoneId)
+{
+    return "zones/" + zoneId + ".conf";
+}
+
+template<typename T>
+void remove(std::vector<T>& v, const T& item)
+{
+    // erase-remove idiom, ask google for explanation
+    v.erase(std::remove(v.begin(), v.end(), item), v.end());
+}
+
 } // namespace
 
-ZonesManager::ZonesManager(const std::string& managerConfigPath)
-    : mWorker(utils::Worker::create()), mDetachOnExit(false)
+ZonesManager::ZonesManager(const std::string& configPath)
+    : mWorker(utils::Worker::create())
+    , mDetachOnExit(false)
 {
     LOGD("Instantiating ZonesManager object...");
 
-    mConfigPath = managerConfigPath;
-    config::loadFromFile(mConfigPath, mConfig);
+    config::loadFromFile(configPath, mConfig);
+    config::loadFromKVStoreWithJsonFile(mConfig.dbPath, configPath, mDynamicConfig);
 
     mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules));
 
@@ -139,8 +152,8 @@ ZonesManager::ZonesManager(const std::string& managerConfigPath)
     mHostConnection.setRevokeDeviceCallback(bind(&ZonesManager::handleRevokeDeviceCall,
                                                  this, _1, _2, _3));
 
-    for (auto& zoneConfig : mConfig.zoneConfigs) {
-        createZone(zoneConfig);
+    for (const auto& zoneConfig : mDynamicConfig.zoneConfigs) {
+        createZone(utils::createFilePath(mConfig.zoneNewConfigPrefix, zoneConfig));
     }
 
     // check if default zone exists, throw ZoneOperationException if not found
@@ -178,11 +191,13 @@ ZonesManager::~ZonesManager()
     LOGD("ZonesManager object destroyed");
 }
 
-void ZonesManager::createZone(const std::string& zoneConfig)
+void ZonesManager::saveDynamicConfig()
 {
-    std::string baseConfigPath = utils::dirName(mConfigPath);
-    std::string zoneConfigPath = utils::getAbsolutePath(zoneConfig, baseConfigPath);
+    config::saveToKVStore(mConfig.dbPath, mDynamicConfig);
+}
 
+void ZonesManager::createZone(const std::string& zoneConfigPath)
+{
     LOGT("Creating Zone " << zoneConfigPath);
     std::unique_ptr<Zone> zone(new Zone(mWorker->createSubWorker(),
                                         mConfig.zonesPath,
@@ -217,7 +232,7 @@ void ZonesManager::createZone(const std::string& zoneConfig)
     // after zone is created successfully, put a file informing that zones are enabled
     if (mZones.size() == 1) {
         if (!utils::saveFileContent(
-                utils::createFilePath(mConfig.zonesPath, "/", ENABLED_FILE_NAME), "")) {
+                utils::createFilePath(mConfig.zonesPath, ENABLED_FILE_NAME), "")) {
             throw ZoneOperationException(ENABLED_FILE_NAME + ": cannot create.");
         }
     }
@@ -238,10 +253,14 @@ void ZonesManager::destroyZone(const std::string& zoneId)
     mZones.erase(it);
 
     if (mZones.size() == 0) {
-        if (!utils::removeFile(utils::createFilePath(mConfig.zonesPath, "/", ENABLED_FILE_NAME))) {
+        if (!utils::removeFile(utils::createFilePath(mConfig.zonesPath, ENABLED_FILE_NAME))) {
             LOGE("Failed to remove enabled file.");
         }
     }
+
+    // update dynamic config
+    remove(mDynamicConfig.zoneConfigs, getConfigName(zoneId));
+    saveDynamicConfig();
 }
 
 void ZonesManager::focus(const std::string& zoneId)
@@ -748,20 +767,19 @@ void ZonesManager::generateNewConfig(const std::string& id,
 {
     namespace fs = boost::filesystem;
 
-    std::string resultFileDir = utils::dirName(resultPath);
-    if (!fs::exists(resultFileDir)) {
-        if (!utils::createEmptyDir(resultFileDir)) {
+    if (fs::exists(resultPath)) {
+        LOGT(resultPath << " already exists, removing");
+        fs::remove(resultPath);
+    } else {
+        std::string resultFileDir = utils::dirName(resultPath);
+        if (!utils::createDirs(resultFileDir, fs::perms::owner_all |
+                                              fs::perms::group_read | fs::perms::group_exe |
+                                              fs::perms::others_read | fs::perms::others_exe)) {
             LOGE("Unable to create directory for new config.");
             throw ZoneOperationException("Unable to create directory for new config.");
         }
     }
 
-    fs::path resultFile(resultPath);
-    if (fs::exists(resultFile)) {
-        LOGT(resultPath << " already exists, removing");
-        fs::remove(resultFile);
-    }
-
     std::string config;
     if (!utils::readFileContent(templatePath, config)) {
         LOGE("Failed to read template config file.");
@@ -788,7 +806,7 @@ void ZonesManager::generateNewConfig(const std::string& id,
     }
 
     // restrict new config file so that only owner (vasum) can write it
-    fs::permissions(resultPath, fs::perms::owner_all |
+    fs::permissions(resultPath, fs::perms::owner_read | fs::perms::owner_write |
                                 fs::perms::group_read |
                                 fs::perms::others_read);
 }
@@ -817,7 +835,7 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
         return;
     }
 
-    const std::string zonePathStr = utils::createFilePath(mConfig.zonesPath, "/", id, "/");
+    const std::string zonePathStr = utils::createFilePath(mConfig.zonesPath, id, "/");
 
     // copy zone image if config contains path to image
     LOGT("Image path: " << mConfig.zoneImagePath);
@@ -834,12 +852,8 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
     }
 
     // generate paths to new configuration files
-    std::string baseDir = utils::dirName(mConfigPath);
-    std::string configDir = utils::getAbsolutePath(mConfig.zoneNewConfigPrefix, baseDir);
-    std::string templateDir = utils::getAbsolutePath(mConfig.zoneTemplatePath, baseDir);
-
-    std::string configPath = utils::createFilePath(templateDir, "/", ZONE_TEMPLATE_CONFIG_PATH);
-    std::string newConfigPath = utils::createFilePath(configDir, "/zones/", id + ".conf");
+    std::string newConfigName = getConfigName(id);
+    std::string newConfigPath = utils::createFilePath(mConfig.zoneNewConfigPrefix, newConfigName);
 
     auto removeAllWrapper = [](const std::string& path) -> bool {
         try {
@@ -852,8 +866,8 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
     };
 
     try {
-        LOGI("Generating config from " << configPath << " to " << newConfigPath);
-        generateNewConfig(id, configPath, newConfigPath);
+        LOGI("Generating config from " << mConfig.zoneTemplatePath << " to " << newConfigPath);
+        generateNewConfig(id, mConfig.zoneTemplatePath, newConfigPath);
 
     } catch (VasumException& e) {
         LOGE("Generate config failed: " << e.what());
@@ -872,6 +886,9 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
         return;
     }
 
+    mDynamicConfig.zoneConfigs.push_back(newConfigName);
+    saveDynamicConfig();
+
     result->setVoid();
 }
 
index a0a2695..5bdb6b5 100644 (file)
@@ -52,7 +52,7 @@ public:
      *
      * @param zoneConfig config of new zone
      */
-    void createZone(const std::string& zoneConfig);
+    void createZone(const std::string& zoneConfigPath);
 
     /**
      * Destroy zone.
@@ -111,8 +111,8 @@ private:
 
     utils::Worker::Pointer mWorker;
     mutable Mutex mMutex; // used to protect mZones
-    ZonesManagerConfig mConfig;
-    std::string mConfigPath;
+    ZonesManagerConfig mConfig; //TODO make it const
+    ZonesManagerDynamicConfig mDynamicConfig;
     HostConnection mHostConnection;
     // to hold InputMonitor pointer to monitor if zone switching sequence is recognized
     std::unique_ptr<InputMonitor> mSwitchingSequenceMonitor;
@@ -121,6 +121,7 @@ private:
     ZoneMap mZones; // map of zones, id is the key
     bool mDetachOnExit;
 
+    void saveDynamicConfig();
     void switchingSequenceMonitorNotify();
     void generateNewConfig(const std::string& id,
                            const std::string& templatePath,
index 1b90e67..544accc 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1-dbus.conf",
                           "zones/console2-dbus.conf",
                           "zones/console3-dbus.conf"],
@@ -6,8 +7,8 @@
     "defaultId" : "ut-zones-manager-console1-dbus",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "",
-    "zoneNewConfigPrefix" : "",
+    "zoneTemplatePath" : "no_need_for_templates_in_this_test",
+    "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/client/ut-client/",
     "runMountPointPrefix" : "",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 8ea6cb8..9df74dc 100644 (file)
@@ -1,9 +1,10 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/zone1.conf", "missing/file/path/missing.conf", "zones/zone3.conf"],
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
     "zoneTemplatePath" : "no_need_for_templates_in_this_test",
-    "zoneNewConfigPrefix" : "",
+    "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-server/",
     "runMountPointPrefix" : "",
     "foregroundId" : "ut-server-zone1",
     "defaultId" : "ut-server-zone1",
index 24e1c4e..697a468 100644 (file)
@@ -1,9 +1,10 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/zone1.conf", "zones/zone2.conf", "zones/zone3.conf"],
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
     "zoneTemplatePath" : "no_need_for_templates_in_this_test",
-    "zoneNewConfigPrefix" : "",
+    "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-server/",
     "runMountPointPrefix" : "",
     "foregroundId" : "ut-server-zone1",
     "defaultId" : "ut-server-zone1",
index f2bcbb9..754594f 100644 (file)
@@ -1,11 +1,12 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1.conf", "missing/file/path/missing.conf", "zones/console3.conf"],
     "runMountPointPrefix" : "",
     "foregroundId" : "ut-zones-manager-console1",
     "defaultId" : "ut-zones-manager-console1",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
+    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 90b9107..3eb9e02 100644 (file)
@@ -1,11 +1,12 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
     "runMountPointPrefix" : "",
     "foregroundId" : "ut-zones-manager-console1",
     "defaultId" : "in_no_way_there_is_a_valid_id_here",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
+    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 49c4c2d..6e02372 100644 (file)
@@ -1,11 +1,12 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
     "runMountPointPrefix" : "",
     "foregroundId" : "this_id_does_not_exist",
     "defaultId" : "ut-zones-manager-console1",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
+    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 4e20535..a80be26 100644 (file)
@@ -1,11 +1,12 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : [],
     "foregroundId" : "",
     "defaultId" : "",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
-    "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
+    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
+    "zoneNewConfigPrefix" : "/tmp/ut-zones/generated-configs/",
     "runMountPointPrefix" : "",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index d72c440..14cea0b 100644 (file)
@@ -1,11 +1,12 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
     "runMountPointPrefix" : "",
     "foregroundId" : "ut-zones-manager-console1",
     "defaultId" : "ut-zones-manager-console1",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
+    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 72b3523..2a55718 100644 (file)
@@ -1,4 +1,5 @@
 {
+    "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1-dbus.conf",
                           "zones/console2-dbus.conf",
                           "zones/console3-dbus.conf"],
@@ -6,7 +7,7 @@
     "defaultId" : "ut-zones-manager-console1-dbus",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
-    "zoneTemplatePath" : "templates",
+    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
     "runMountPointPrefix" : "",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
index 75b894a..3ed7319 100644 (file)
@@ -36,6 +36,7 @@
 
 namespace {
 const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf
+const bool AS_ROOT = true;
 
 struct Fixture {
     vasum::utils::ScopedDir mZonesPathGuard;
@@ -65,12 +66,12 @@ BOOST_AUTO_TEST_CASE(ConstructorDestructorTest)
 
 BOOST_AUTO_TEST_CASE(BuggyConfigTest)
 {
-    BOOST_REQUIRE_THROW(Server(BUGGY_CONFIG_PATH).run(), ConfigException);
+    BOOST_REQUIRE_THROW(Server(BUGGY_CONFIG_PATH).run(AS_ROOT), ConfigException);
 }
 
 BOOST_AUTO_TEST_CASE(MissingConfigTest)
 {
-    BOOST_REQUIRE_THROW(Server(MISSING_CONFIG_PATH).run(), ConfigException);
+    BOOST_REQUIRE_THROW(Server(MISSING_CONFIG_PATH).run(AS_ROOT), ConfigException);
 }
 
 BOOST_AUTO_TEST_CASE(TerminateTest)
@@ -83,13 +84,13 @@ BOOST_AUTO_TEST_CASE(TerminateRunTest)
 {
     Server s(TEST_CONFIG_PATH);
     s.terminate();
-    s.run();
+    s.run(AS_ROOT);
 }
 
 BOOST_AUTO_TEST_CASE(RunTerminateTest)
 {
     Server s(TEST_CONFIG_PATH);
-    std::future<void> runFuture = std::async(std::launch::async, [&] {s.run();});
+    std::future<void> runFuture = std::async(std::launch::async, [&] {s.run(AS_ROOT);});
 
     // give a chance to run a thread
     std::this_thread::sleep_for(std::chrono::milliseconds(200));
index 5b29340..5925052 100644 (file)
@@ -1066,6 +1066,50 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
     BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), "");
 }
 
+BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistenceTest)
+{
+    const std::string zone = "test1";
+
+    Latch callDone;
+    auto resultCallback = [&]() {
+        callDone.set();
+    };
+
+    auto getZoneIds = []() -> std::vector<std::string> {
+        ZonesManager cm(EMPTY_DBUS_CONFIG_PATH);
+        cm.startAll();
+
+        DbusAccessory dbus(DbusAccessory::HOST_ID);
+        return dbus.callMethodGetZoneIds();
+    };
+
+    BOOST_CHECK(getZoneIds().empty());
+
+    // create zone
+    {
+        ZonesManager cm(EMPTY_DBUS_CONFIG_PATH);
+        DbusAccessory dbus(DbusAccessory::HOST_ID);
+        dbus.callAsyncMethodCreateZone(zone, resultCallback);
+        BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+    }
+
+    {
+        auto ids = getZoneIds();
+        BOOST_CHECK_EQUAL(1, ids.size());
+        BOOST_CHECK(ids.at(0) == zone);
+    }
+
+    // destroy zone
+    {
+        ZonesManager cm(EMPTY_DBUS_CONFIG_PATH);
+        DbusAccessory dbus(DbusAccessory::HOST_ID);
+        dbus.callAsyncMethodDestroyZone(zone, resultCallback);
+        BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+    }
+
+    BOOST_CHECK(getZoneIds().empty());
+}
+
 BOOST_AUTO_TEST_CASE(StartShutdownZoneTest)
 {
     const std::string zone1 = "ut-zones-manager-console1-dbus";