Skip to content

迁移配置至 dconfig - #109

Open
glyvut wants to merge 2 commits into
linuxdeepin:masterfrom
glyvut:master
Open

迁移配置至 dconfig#109
glyvut wants to merge 2 commits into
linuxdeepin:masterfrom
glyvut:master

Conversation

@glyvut

@glyvut glyvut commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Migrate DDM configuration to DConfig and package the required schemas and runtime dependencies.

Enhancements:

  • Migrate DDM configuration storage from INI files to DConfig schemas for main and state settings.
  • Load and persist configuration through DConfig while preserving supported value types and key mappings.

Build:

  • Add the Dtk6 Core dependency and install DConfig schemas and state metadata.
  • Bump the project version to 0.3.9 and update packaging dependencies.

Deployment:

  • Update runtime temporary-directory configuration for the DConfig-based layout.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: glyvut

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions

Copy link
Copy Markdown

TAG Bot

TAG: 0.3.9
EXISTED: no
DISTRIBUTION: unstable

@sourcery-ai

sourcery-ai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Reviewer's Guide

DDM now stores its main and state configuration in typed DConfig schemas instead of INI files, with compatibility key mappings and runtime initialization after QCoreApplication creation; build and distribution packaging now provide Dtk6 Core and install the corresponding schemas.

Sequence diagram for runtime DConfig initialization and persistence

sequenceDiagram
    participant Main as DaemonApp main
    participant App as QCoreApplication
    participant Config as ConfigBase
    participant DConfig as DConfig
    participant Schema as DConfig schema

    Main->>App: construct DaemonApp
    Main->>Config: mainConfig.load()
    Config->>DConfig: create(appId, name, ...)
    DConfig->>Schema: read typed values
    Schema-->>DConfig: configuration values
    DConfig-->>Config: value(key)
    Config-->>Main: populated configuration
    Main->>Config: stateConfig.load()
    Main->>Config: save(section, entry)
    Config->>DConfig: setValue(key, typedValue)
    DConfig->>DConfig: reset(key) when default
Loading

File-Level Changes

Change Details Files
Replace INI-file configuration persistence with typed DConfig-backed loading and saving.
  • Add DConfig key translation for legacy section/entry names and renamed settings.
  • Read schema-defined QVariant values into existing configuration entries, including boolean and list conversions.
  • Persist changed values through DConfig, resetting entries that match defaults.
  • Cache DConfig instances by application and configuration name.
src/common/ConfigReader.cpp
src/common/Configuration.h
Package DDM’s DConfig schemas and state metadata as part of the install.
  • Add generated main and state schema JSON files under the DConfig configuration directory.
  • Define schema entries for application configuration and last-session state.
  • Remove the legacy configuration path and system configuration directory CMake settings.
data/CMakeLists.txt
data/dconfig/org.deepin.dde.ddm.json.in
data/dconfig/org.deepin.dde.ddm.state.json
CMakeLists.txt
Integrate DConfig into the build and defer configuration initialization until runtime.
  • Require and link Dtk6 Core.
  • Guard configuration loading until QCoreApplication exists.
  • Explicitly load main and state configuration after creating the daemon application.
CMakeLists.txt
src/common/CMakeLists.txt
src/common/ConfigReader.cpp
src/daemon/DaemonApp.cpp
.github/workflows/ddm-archlinux-build.yml
Update release and distribution packaging for the migration.
  • Bump the project version to 0.3.9.
  • Add Dtk6 Core packaging dependencies and install metadata.
  • Update temporary-file configuration for the new state storage location.
CMakeLists.txt
debian/control
debian/changelog
services/ddm-tmpfiles.conf.in

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/common/Configuration.cpp" line_range="37" />
<code_context>
-        auto it = m_entries.find(name);
-        if (it != m_entries.end())
-            return it.value();
-        return nullptr;
-    }
-
</code_context>
<issue_to_address>
**issue (bug_risk):** When either DConfig instance cannot be created, `createConfig` returns `nullptr`, but `initConfiguration` leaves the corresponding global null and the daemon later dereferences it through calls such as `mainConfig->autologinUser()`, causing a startup or first-request crash.

**Triggers:** When the dconfig daemon is unavailable or configuration creation fails.

**Suggested fix:** Treat initialization failure as fatal with a clear error and exit, or keep the daemon disabled until both configuration pointers are valid.
</issue_to_address>

### Comment 2
<location path="src/common/Configuration.cpp" line_range="48" />
<code_context>
+                return nullptr;
+
+            if (config->isInitializeSucceeded())
+                return config;
+
+            QEventLoop loop;
</code_context>
<issue_to_address>
**issue (bug_risk):** After `configInitializeFailed` or the five-second timeout, `createConfig` still returns the uninitialized configuration object instead of reporting failure, so callers read and write an object whose DConfig state was never initialized.

**Triggers:** When asynchronous DConfig initialization fails or does not complete within five seconds.

**Suggested fix:** Track whether initialization succeeded and return `nullptr` or otherwise fail initialization when the failure signal or timeout ends the event loop.

```suggestion
            return config->isInitializeSucceeded() ? config : nullptr;
```
</issue_to_address>

### Comment 3
<location path="src/daemon/DaemonApp.cpp" line_range="123-124" />
<code_context>
         std::cout << "Usage: ddm [options]\n"
                   << "Options: \n"
-                  << "  --example-config    Print the complete current configuration to stdout" << std::endl;
+                  << "  --test-mode    Start daemon in test mode" << std::endl;

         return EXIT_FAILURE;
</code_context>
<issue_to_address>
**issue (bug_risk):** The help text advertises `--test-mode`, but `main` only checks `--help` and never parses or applies `--test-mode`; invoking it starts the normal daemon rather than test mode.

**Triggers:** When an operator or test invokes ddm with `--test-mode`.

**Suggested fix:** Implement the test-mode branch before constructing the normal daemon, or remove the option from the help output.

```suggestion
                  << "Options: \n";
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/common/Configuration.cpp Outdated
Comment thread src/common/Configuration.cpp Outdated
Comment thread src/daemon/DaemonApp.cpp Outdated
@glyvut
glyvut marked this pull request as draft August 27, 2026 06:26
@glyvut
glyvut marked this pull request as ready for review August 27, 2026 08:17

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/common/ConfigReader.cpp" line_range="2" />
<code_context>
 /*
- * INI Configuration parser classes
+ * INI Configuration parser classes (DConfig backed)
  * Copyright (C) 2014 Martin Bříza <mbriza@redhat.com>
  *
</code_context>
<issue_to_address>
**nitpick:** The file header still describes these classes as an INI configuration parser even though the implementation no longer reads or writes INI files and instead uses DConfig. This misleads maintainers about the storage backend and the behavior of ConfigBase.

**Suggested fix:** Update the header comments in both files to describe the DConfig-backed configuration wrapper.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/common/ConfigReader.cpp
glyvut added 2 commits August 27, 2026 16:39
Replace the custom INI based ConfigReader with typed DConfig wrappers
generated by dconfig2cpp from the org.deepin.dde.ddm DSG schemas. The
main configuration and the last user/session state are now managed by
the dconfig daemon instead of /etc/ddm.conf and ~ddm/state.conf.

用 DConfig 替换自研 INI 解析器 ConfigReader,通过 dconfig2cpp 从
org.deepin.dde.ddm DSG schema 生成强类型配置封装。主配置与上次用
户/会话状态改由 dconfig 守护进程统一存储管理,不再使用
/etc/ddm.conf 与 ~ddm/state.conf。

Log: 配置系统迁移到 dconfig
Influence: 配置由 dconfig 统一管理,需安装 DSG schema;构建新增
libdtk6core-dev 依赖;不再支持 /etc/ddm.conf 等旧配置文件。
@glyvut
glyvut marked this pull request as draft August 27, 2026 08:50
@glyvut
glyvut marked this pull request as ready for review August 27, 2026 08:52

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="CMakeLists.txt" line_range="120-124" />
<code_context>
-set(CONFIG_FILE                 "${CMAKE_INSTALL_FULL_SYSCONFDIR}/ddm.conf"        CACHE PATH      "Path of the ddm config file")
</code_context>
<issue_to_address>
**issue:** The CMake cache variables `CONFIG_FILE`, `CONFIG_DIR`, and `SYSTEM_CONFIG_DIR` are removed while the man-page templates still reference them during configuration. The generated `ddm(1)`, `ddm.conf(5)`, and `ddm-state.conf(5)` documentation therefore contains empty configuration paths instead of describing the DConfig storage locations.

**Triggers:** When `BUILD_MAN_PAGES` is enabled.

**Suggested fix:** Update the man-page templates and their configure inputs to document the DConfig schema and state locations, or retain suitable path variables for the generated documentation.
</issue_to_address>

### Comment 2
<location path="src/common/ConfigReader.cpp" line_range="92-100" />
<code_context>
+            return key;
+        }
+
+        DTK_CORE_NAMESPACE::DConfig *dconfigFor(const QString &appId, const QString &name) {
+            static QHash<QString, DTK_CORE_NAMESPACE::DConfig *> s_configs;
+            const QString cacheKey = appId + QLatin1Char('/') + name;
+            auto it = s_configs.constFind(cacheKey);
+            if (it != s_configs.constEnd())
+                return it.value();
+            auto *config = DTK_CORE_NAMESPACE::DConfig::create(appId, name, QString(), nullptr);
+            s_configs.insert(cacheKey, config);
+            return config;
+        }
+
</code_context>
<issue_to_address>
**nitpick (bug_risk):** Every DConfig object created by `dconfigFor` is allocated with a null parent and retained in a process-global `QHash` without any ownership or cleanup. Each distinct app/name pair permanently leaks its DConfig object for the lifetime of the process.

**Triggers:** When additional distinct DConfig configurations are requested in a long-running process.

**Suggested fix:** Give the objects an owning Qt parent or store them in an owning smart pointer/container and release them during shutdown.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread CMakeLists.txt
Comment on lines -120 to 124
set(CONFIG_FILE "${CMAKE_INSTALL_FULL_SYSCONFDIR}/ddm.conf" CACHE PATH "Path of the ddm config file")
set(CONFIG_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/ddm.conf.d" CACHE PATH "Path of the ddm config directory")
set(ACCOUNTSSERVICE_DATA_DIR "/var/lib/AccountsService" CACHE PATH "Path of the accountsservice data directory")
set(SYSTEM_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/lib/ddm/ddm.conf.d" CACHE PATH "Path of the system ddm config directory")
set(LOG_FILE "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/log/ddm.log" CACHE PATH "Path of the ddm log file")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The CMake cache variables CONFIG_FILE, CONFIG_DIR, and SYSTEM_CONFIG_DIR are removed while the man-page templates still reference them during configuration. The generated ddm(1), ddm.conf(5), and ddm-state.conf(5) documentation therefore contains empty configuration paths instead of describing the DConfig storage locations.

Triggers: When BUILD_MAN_PAGES is enabled.

Suggested fix: Update the man-page templates and their configure inputs to document the DConfig schema and state locations, or retain suitable path variables for the generated documentation.

Comment on lines +92 to +100
DTK_CORE_NAMESPACE::DConfig *dconfigFor(const QString &appId, const QString &name) {
static QHash<QString, DTK_CORE_NAMESPACE::DConfig *> s_configs;
const QString cacheKey = appId + QLatin1Char('/') + name;
auto it = s_configs.constFind(cacheKey);
if (it != s_configs.constEnd())
return it.value();
auto *config = DTK_CORE_NAMESPACE::DConfig::create(appId, name, QString(), nullptr);
s_configs.insert(cacheKey, config);
return config;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (bug_risk): Every DConfig object created by dconfigFor is allocated with a null parent and retained in a process-global QHash without any ownership or cleanup. Each distinct app/name pair permanently leaks its DConfig object for the lifetime of the process.

Triggers: When additional distinct DConfig configurations are requested in a long-running process.

Suggested fix: Give the objects an owning Qt parent or store them in an owning smart pointer/container and release them during shutdown.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 96 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 代码变更将 DDM 配置系统从自研 INI 解析器迁移至 DConfig,实现清晰、结构良好。未发现安全漏洞,代码逻辑正确,性能合理。存在少量代码质量问题(文件末尾缺少换行符、变量命名语义变化),不影响功能正确性。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. src/common/Configuration.h:96 - 文件末尾缺少换行符(No newline at end of file),部分编译器/工具可能产生警告
  2. src/common/ConfigReader.cpp:93 - dconfigFor() 函数在静态 QHash 中缓存 DConfig 对象但从不释放,技术上是资源泄漏。对于守护进程可接受,但不符合理想资源管理实践

建议: 代码语法正确,DConfig 集成逻辑合理。load() 方法中正确检查了 QCoreApplication::instance() 以避免静态初始化阶段调用 DConfig。建议修复文件末尾换行符问题,并考虑在应用关闭时清理缓存的 DConfig 对象。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. src/common/Configuration.h:96 - 文件末尾缺少换行符
  2. src/common/ConfigReader.cpp:191 - ConfigBase 的成员变量 m_path、m_configDir、m_sysConfigDir 在迁移后语义已变化(从文件路径变为 DConfig 标识符),但变量名未更新,可能误导维护者

建议: 新代码使用匿名命名空间封装辅助函数(dconfigKey、dconfigFor、variantToString、stringToVariant),结构清晰。DConfig schema 文件包含完整的 zh_CN 翻译。注释充分解释了 DConfig 与 QCoreApplication 的交互关系。建议更新变量名以匹配新语义,并在文件末尾添加换行符。


3. 代码性能 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: DConfig 对象在 dconfigFor() 中缓存避免重复创建,dconfigKey() 中的覆盖映射使用静态 QHash 一次初始化。load/save 操作通过 DConfig API 直接读写,无性能瓶颈。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: DConfig 通过 dconfig 守护进程统一管理配置,比 INI 文件提供更好的访问控制。DConfig schema 中 haltCommand 和 rebootCommand 设置为 read/private 权限,仅 ddm 进程可读。autologinUser 和 autologinSession 设置为 readwrite/public,符合登录管理器设计需求。无硬编码密钥、无命令注入风险。


💡 改进建议代码示例

// 修复1: Configuration.h 文件末尾添加换行符
#endif // DDM_CONFIGURATION_H

// 修复2: ConfigReader.cpp - 重命名变量以匹配新语义
//  ConfigBase 类定义中ConfigReader.h//  m_path 重命名为 m_schemaName
//  m_configDir 重命名为 m_appId
//  m_sysConfigDir 移除不再使用// 修复3: 可选 - 清理 DConfig 缓存
//  DaemonApp.cpp  app.exec() 返回后添加清理代码
// 或使用 QCoreApplication::aboutToQuit 信号

本报告由 AI 代码审查工具自动生成

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants