Skip to content

迁移配置至 dconfig - #109

Draft
glyvut wants to merge 1 commit into
linuxdeepin:masterfrom
glyvut:master
Draft

glyvut wants to merge 1 commit into
linuxdeepin:masterfrom
glyvut:master

Conversation

@glyvut

@glyvut glyvut commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary by Sourcery

将 DDM 的配置管理迁移到 DConfig,并调整会话发现、登录协议和启动流程以配合新的配置来源。

New Features:

  • 将 DDM 配置迁移至 DConfig,并提供对应的配置 schema。
  • 通过显示管理器协议向 greeter 提供 X11/Wayland 会话目录,并支持按会话桌面文件路径登录。

Enhancements:

  • 移除旧的配置文件解析、状态持久化和示例配置接口,改由 DConfig 异步初始化并在配置就绪后启动相关服务。
  • 更新配置文档、架构说明和会话处理逻辑以适配新的配置及 greeter 负责的会话状态管理。

Build:

  • 增加 Dtk6 DConfig 构建依赖、配置代码生成和 schema 安装。
  • 更新 Arch Linux 与 Debian 构建依赖配置。

Documentation:

  • 更新 ddm 配置手册及架构文档,反映 DConfig 和 greeter 会话管理方式。

Chores:

  • 移除已废弃的 ddm-state.conf 文档及旧配置读取组件。

@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

github-actions Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

TAG Bot

TAG: 0.4.1
EXISTED: no
DISTRIBUTION: unstable

@sourcery-ai

sourcery-ai Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Migrates DDM’s main and state settings from layered INI files to typed DConfig schemas installed in the shared DSG directory, adds runtime-safe initialization before daemon startup, and updates build dependencies, packaging, paths, version metadata, and documentation.

Sequence diagram for DConfig initialization before daemon startup

sequenceDiagram
    participant Main as Daemon main
    participant App as DaemonApp
    participant MainConfig as mainConfig
    participant StateConfig as stateConfig
    participant DConfig as DConfig

    Main->>App: DaemonApp(argc, argv)
    App-->>Main: QCoreApplication available
    Main->>MainConfig: load()
    MainConfig->>DConfig: create(org.deepin.dde.ddm, org.deepin.dde.ddm)
    DConfig-->>MainConfig: typed configuration values
    Main->>StateConfig: load()
    StateConfig->>DConfig: create(org.deepin.dde.ddm, org.deepin.dde.ddm.state)
    DConfig-->>StateConfig: persisted state values
    Main->>App: exec()
Loading

File-Level Changes

Change Details Files
Replace INI-based configuration and state persistence with typed DConfig-backed schemas.
  • Add generated main and state schemas under the shared DSG configuration directory.
  • Map legacy section/key names to DConfig keys, including renamed settings.
  • Load typed DConfig values into existing configuration entries and persist non-default values through DConfig, resetting defaults when appropriate.
  • Use the application ID and state suffix to address main and state configuration objects.
src/common/ConfigReader.cpp
src/common/Configuration.h
data/dconfig/org.deepin.dde.ddm.json.in
data/dconfig/org.deepin.dde.ddm.state.json
Defer configuration loading until Qt initialization and load both configurations before daemon startup.
  • Guard DConfig access when no QCoreApplication exists.
  • Explicitly load main and state configuration after constructing DaemonApp and before entering the event loop.
src/common/ConfigReader.cpp
src/daemon/DaemonApp.cpp
Integrate DConfig into the build and packaging layout.
  • Require and link Dtk6Core.
  • Install generated schemas at the standard DSG path.
  • Update Arch and Debian dependency metadata, runtime paths, tmpfiles configuration, and project version to 0.4.1.
CMakeLists.txt
src/common/CMakeLists.txt
data/CMakeLists.txt
.github/workflows/ddm-archlinux-build.yml
debian/control
debian/changelog
services/ddm-tmpfiles.conf.in
src/common/Constants.h.in
Update user-facing documentation for DConfig-managed configuration and state.
  • Revise configuration, state, and command man pages for the new schema-backed settings and paths.
data/man/ddm.conf.rst.in
data/man/ddm-state.conf.rst.in
data/man/ddm.rst.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 Outdated
@glyvut
glyvut force-pushed the master branch 2 times, most recently from c6ba540 to 3de45e4 Compare August 27, 2026 08:39
@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 thread src/common/ConfigReader.cpp Outdated
@deepin-bot

deepin-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.4.0
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #115

@glyvut
glyvut force-pushed the master branch 2 times, most recently from 637b4c5 to ad2fdeb Compare October 12, 2026 08:51
@wineee
wineee requested a balanced review from Copilot October 12, 2026 09:48

Copilot AI 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.

🟡 Changes recommended

Global writable autologin settings, missing legacy-value migration, and DConfig packaging/interface defects must be addressed. / 必须解决全局可写自动登录、旧配置迁移缺失及 DConfig 打包接口问题。

7 open findings
What changed in this PR

Migrates DDM configuration and session state from INI files to DConfig. / 将 DDM 配置和会话状态从 INI 迁移至 DConfig。

Changes:

  • Adds DConfig-backed loading, saving, and schemas. / 新增 DConfig 读写及 schema。
  • Updates build dependencies, packaging, and version to 0.4.1. / 更新构建依赖、打包及版本。
  • Revises configuration documentation. / 更新配置文档。
File Description
CMakeLists.txt Adds DTK/DConfig setup and version bump. / 添加 DTK/DConfig 配置并升级版本。
.github/​workflows/​ddm-archlinux-build.yml Adds Arch DTK dependency. / 添加 Arch DTK 依赖。
debian/​changelog Records release changes. / 记录发行变更。
debian/​control Adds Debian DTK dependencies. / 添加 Debian DTK 依赖。
services/​ddm-tmpfiles.conf.in Removes obsolete state-file note. / 移除过时状态文件说明。
src/​common/​CMakeLists.txt Links DTK Core. / 链接 DTK Core。
src/​common/​Constants.h.in Removes INI path constants. / 移除 INI 路径常量。
src/​common/​Configuration.h Defines DConfig resources. / 定义 DConfig 资源。
src/​common/​ConfigReader.cpp Replaces INI persistence with DConfig. / 使用 DConfig 替代 INI 持久化。
src/​daemon/​DaemonApp.cpp Reloads configuration after application creation. / 应用创建后重新加载配置。
data/​CMakeLists.txt Installs DConfig schemas. / 安装 DConfig schema。
data/​dconfig/​org.deepin.dde.ddm.json.in Defines main configuration schema. / 定义主配置 schema。
data/​dconfig/​org.deepin.dde.ddm.state.json Defines state schema. / 定义状态 schema。
data/​man/​ddm.rst.in Documents DConfig files. / 说明 DConfig 文件。
data/​man/​ddm.conf.rst.in Documents migrated settings. / 说明迁移后的配置项。
data/​man/​ddm-state.conf.rst.in Documents state resource. / 说明状态资源。

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread data/dconfig/org.deepin.dde.ddm.json.in
Comment thread src/common/ConfigReader.cpp Outdated
Comment thread CMakeLists.txt Outdated
"name[zh_CN]": "关机命令",
"description": "Halt command.",
"description[zh_CN]": "关机命令。",
"permissions": "read",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

后续按需调整

Comment thread src/common/CMakeLists.txt Outdated
Comment thread data/dconfig/org.deepin.dde.ddm.json.in
Comment thread data/dconfig/org.deepin.dde.ddm.state.json Outdated
@glyvut
glyvut marked this pull request as draft October 13, 2026 00:49
@glyvut
glyvut marked this pull request as ready for review October 13, 2026 13:10

@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 4 issues

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

## Individual Comments

### Comment 1
<location path="src/common/Configuration.h" line_range="83" />
<code_context>
     );

-    Config(StateConfig, []()->QString{auto tmp = getpwnam("ddm"); return tmp ? QString::fromLocal8Bit(tmp->pw_dir) : QStringLiteral(STATE_DIR);}().append(QStringLiteral("/state.conf")), QString(), QString(),
+    Config(StateConfig, _S(DDM_DCONFIG_APP_ID ".state"), _S(DDM_DCONFIG_APP_ID), QString(),
         Section(Last,
             Entry(Session,         QString,     QString(),                                      _S("Name of the session for the last logged-in user.\n"
</code_context>
<issue_to_address>
**Writable session state runs attacker code**

When a local user sets `lastSession` to a desktop file they control and DDM uses the remembered session for configured autologin, `stateConfig.Last.Session` is accepted from DConfig and passed to `Session::setTo()`, where an absolute path bypasses the configured session directories; DDM parses that file's `Exec` entry and launches it during passwordless autologin, running the attacker's command as the autologin user.

Restrict writes to the state key and reject session paths that do not resolve to files inside the configured, trusted session directories.
</issue_to_address>

### Comment 2
<location path="CMakeLists.txt" line_range="87" />
<code_context>
 qt_standard_project_setup(REQUIRES 6.6)

+# DTK (DConfig)
+find_package(Dtk6 REQUIRED COMPONENTS Core)
+
 # Uninstall target
</code_context>
<issue_to_address>
**Nix package fails to configure**

When the Nix package is built, `find_package(Dtk6 REQUIRED COMPONENTS Core)` cannot find Dtk6 in the Nix build environment, so CMake configuration fails before the package can build.

Add the Nix package providing Dtk6 Core to `nix/default.nix` build inputs.
</issue_to_address>

### Comment 3
<location path="src/common/ConfigReader.cpp" line_range="247" />
<code_context>
+            if (e->matchesDefault())
+                config->reset(key);
+            else
+                config->setValue(key, stringToVariant(config, key, e->value()));
         };

</code_context>
<issue_to_address>
**Most settings stay read-only**

When an administrator tries to change a non-autologin setting through DConfig, the main schema marks those settings as read-only, so DConfig rejects the updates and administrators cannot configure settings that were writable through the previous INI files.

Mark the non-autologin settings that administrators are meant to configure as writable in the schema.
</issue_to_address>

### Comment 4
<location path="src/common/ConfigReader.cpp" line_range="105-114" />
<code_context>
+            return config.data();
+        }
+
+        QString variantToString(const QVariant &value) {
+            if (value.typeId() == QMetaType::QStringList)
+                return value.toStringList().join(QLatin1Char(','));
+            if (value.typeId() == QMetaType::QVariantList) {
+                QStringList stringList;
+                const auto list = value.toList();
+                for (const QVariant &item : list)
+                    stringList << item.toString();
+                return stringList.join(QLatin1Char(','));
+            }
+            return value.toString();
+        }
</code_context>
<issue_to_address>
**Comma-containing paths are split**

When a DConfig list element, such as a namespace path, contains a comma, `variantToString` joins DConfig list elements with commas, and `ConfigEntry::setValue` splits that string on commas, so a single path containing a comma becomes multiple paths. `UserSession::childModifier` then fails to open a namespace path and aborts session startup.

Preserve list elements directly when loading DConfig arrays instead of serializing and reparsing them as comma-separated text.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread src/common/Configuration.h Outdated
Comment thread CMakeLists.txt Outdated
Comment thread src/common/ConfigReader.cpp Outdated
Comment thread src/common/ConfigReader.cpp Outdated
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

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

Fail


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交将 DDM 配置系统从 INI 文件迁移到 DConfig 框架,代码结构清晰,逻辑正确,未发现安全漏洞。DConfig 框架通过 D-Bus 守护进程管理配置,比原始 INI 文件方式更安全。建议在 save() 方法中增加 config->isValid() 检查以保持与 load() 的一致性。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

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

建议: 建议在 save() 方法中增加 config->isValid() 检查,与 load() 保持一致。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

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

建议: 在 Configuration.h 文件末尾添加一个换行符。


3. 代码性能 ✅

评价: 优秀 ✅ 通过

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

建议: DConfig 实例通过静态 QHash 缓存,避免了重复创建。load() 和 save() 方法从原来的文件 I/O 操作改为 DConfig D-Bus 调用,代码大幅简化,性能合理。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

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

建议: DConfig 框架通过 D-Bus 守护进程管理配置,比原始 INI 文件方式更安全。DConfig schema 中大多数配置项设置了 permissions: read 和 visibility: private,仅 autologinUser 和 autologinSession 设置为 readwrite/public(功能需要)。无硬编码密钥、无命令注入风险、无敏感信息泄露。


💡 改进建议代码示例

// 暂无代码示例

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

Comment thread debian/changelog Outdated
Comment thread src/common/ConfigReader.cpp Outdated
@glyvut
glyvut marked this pull request as draft October 19, 2026 06:19
@glyvut
glyvut force-pushed the master branch 6 times, most recently from 8468527 to 0d456ff Compare October 19, 2026 08:12
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.

4 participants