New upstream version 2.5.1.0

This commit is contained in:
tianshaoshuai 2024-05-25 10:38:31 +08:00
parent 3f8b2fc8c6
commit 790afc635f
87 changed files with 3976 additions and 3124 deletions

327
debian/changelog vendored Normal file
View File

@ -0,0 +1,327 @@
libkysdk-base (2.5.1.0-0k0.8) nile; urgency=medium
* BUG
* 需求号:无
* 其他改动说明:
1. 配置组新增permission,description,summary属性
2. permission权限新增final,stable
3. conf2与gsettings联动,联动后gsettings设置的同步到conf2,反向同理
4. 原本已经做了设置的应用,升级到接入conf2后,原本的设置保留
5. 新增trigger,应用装包,目录下出现新的配置文件,自动执行reload
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Mon, 20 May 2024 15:18:53 +0800
libkysdk-base (2.4.1.0-0k1.7) nile; urgency=medium
* BUG#222596 【dbus】libkysdk-base com.kylin.kysdk.conf2系统总线服务级和方法级整改
* 需求号:无
* 其他改动说明1. 修复服务级管控无法读取到白名单问题
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Fri, 17 May 2024 17:59:57 +0800
libkysdk-base (2.4.1.0-0k1.6) nile; urgency=medium
* BUG
#222596 【dbus】libkysdk-base com.kylin.kysdk.conf2系统总线服务级和方法级整改
#227605 【华为云】【guesetos】【控制面板】控制面板缺少电源模块
#227626 【需求26164】【华为云】【guestos】【真机】会话管理器显示/隐藏电源操作-组件自身配置
* 需求号:无
* 其他改动说明:无
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Fri, 17 May 2024 09:32:19 +0800
libkysdk-base (2.4.1.0-0k1.5) nile; urgency=medium
* BUG
* 需求号:无
* 其他改动说明:
1. 修复xml2yaml工具生成时枚举缩进位置不对的问题
2. 修复读数据库到内存(db2dict)的逻辑
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Wed, 15 May 2024 15:34:45 +0800
libkysdk-base (2.4.1.0-0k1.4) nile; urgency=medium
* BUG
#226776 【conf2】新增对同目录里有相同的配置项的处理中点击下载按钮选择新建文件夹时终端报错核心已转储
#226686 【conf2】调整目录优先级执行报错 [用例#909448]
* 需求号:无
* 其他改动说明:
1. 更新gschema.xml转yaml工具
2. 增加部分日志
3. 修复服务管控中,非白名单应用调用dbus接口时虽然报错但接口仍然被调用的问题
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Thu, 09 May 2024 10:44:27 +0800
libkysdk-base (2.4.1.0-0k1.3) nile; urgency=medium
* BUG#222596 【dbus】libkysdk-base com.kylin.kysdk.conf2系统总线服务级和方法级整改
* 需求号:无
* 其他改动说明:
1. 修改pc文件中的版本号
2. 修改session服务启动时kylin-config目录不存在会报错的问题
3. 修改kdk_conf2_set_string会多一对单引号的问题
4. conf2服务生成统一视图时增加处理final和stable属性,组增加属性
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Tue, 07 May 2024 14:53:36 +0800
libkysdk-base (2.4.1.0-0k1.2) nile; urgency=medium
* BUG
* 需求号:无
* 其他改动说明修改control文件依赖
* 其他改动影响域:无
-- shaozhimin <shaozhimin@kylinos.cn> Fri, 26 Apr 2024 15:44:33 +0800
libkysdk-base (2.4.1.0-0k1.1) nile; urgency=medium
* BUG
* 需求号:无
* 其他改动说明:修改数据库表结构
* 其他改动影响域:无
-- szm-min <shaozhimin@kylinos.cn> Thu, 25 Apr 2024 14:21:27 +0800
libkysdk-base (2.4.1.0-0k1.0) nile; urgency=medium
* BUG
* 需求号:
#28841 调整目录优先级
#28842 新增对同目录相同项的处理
* 其他改动说明:
1. 新增兼容并发读写功能
2. 新增工具类包libkysdk-conf2-tools工具不在集成在libkysdk-conf2包里
3. 新增日志记录功能
4. 配置文件里去掉children和keys关键字
5. 所有固定关键字前面加下划线统一格式
6. 取消common目录,通用配置存放位置可以除basic以外的所有目录
* 其他改动影响域:无
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Fri, 19 Apr 2024 14:43:46 +0800
libkysdk-base (2.4.1.0-0k0.2) nile; urgency=medium
* BUG
* 需求号:无
* 其他改动说明整机导入合入bug#221702 【CPM20240409009145】 【PanguX-5.6.0.17 + BIOS 1.01】【HW】【系统功能】【Freetest】系统监视器下物理内存使用量显示不正确已用内存比物理内存总量还大(2/2 DUTs)。(一般+必现+常用功能)修复
* 其他改动影响域:无
-- szm-min <shaozhimin@kylinos.cn> Mon, 15 Apr 2024 16:03:10 +0800
libkysdk-base (2.4.1.0-0k0.1) nile; urgency=medium
* BUG
* 需求号:无
* 其他改动说明:更新 diagnostics symbols文件
* 其他改动影响域:无
-- szm-min <shaozhimin@kylinos.cn> Mon, 01 Apr 2024 18:13:31 +0800
libkysdk-base (2.4.1.0-0k0.0) nile; urgency=medium
* BUG
* 需求号:#26164 华为云桌面默认关闭接口在HWS及HCSO做一个开启关闭休眠接口开关需求
* 其他改动说明:任务#203739:需求26164的conf2适配内容同步2403u1版本 / 迁移华为云桌面192292 sdk提供conf2机制支持睡眠、休眠、切换用户、关机可配置
* 其他改动影响域:无
-- szm-min <shaozhimin@kylinos.cn> Wed, 27 Mar 2024 09:03:47 +0800
libkysdk-base (2.3.0.0-0k0.14) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 添加symbols文件
-- szm-min <shaozhimin@kylinos.cn> Wed, 27 Dec 2023 09:10:05 +0800
libkysdk-base (2.3.0.0-0k0.13) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 移除CMake对老旧C++的绑定
-- szm-min <shaozhimin@kylinos.cn> Wed, 20 Dec 2023 16:30:33 +0800
libkysdk-base (2.3.0.0-0k0.12) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 修复已知的conf2模块导致的崩溃问题,上传可视化工具
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Tue, 12 Dec 2023 16:46:35 +0800
libkysdk-base (2.3.0.0-0k0.11) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 恢复diagnostics 模块内容
-- szm-min <shaozhimin@kylinos.cn> Tue, 12 Dec 2023 14:50:30 +0800
libkysdk-base (2.3.0.0-0k0.10) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : conf2模块创建用户配置目录时所有者为root的问题处理
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Mon, 04 Dec 2023 17:24:42 +0800
libkysdk-base (2.3.0.0-0k0.9) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 修改conf2模块pc文件中的Requires
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Fri, 01 Dec 2023 14:15:59 +0800
libkysdk-base (2.3.0.0-0k0.8) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 修改conf2模块pc文件
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Fri, 01 Dec 2023 10:35:17 +0800
libkysdk-base (2.3.0.0-0k0.7) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 修改conf2模块pc文件
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Fri, 01 Dec 2023 09:12:19 +0800
libkysdk-base (2.3.0.0-0k0.6) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 :修复conf2模块的部分问题
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Thu, 30 Nov 2023 14:11:14 +0800
libkysdk-base (2.3.0.0-0k0.5) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 :修改pc文件和动态库版本
-- szm-min <shaozhimin@kylinos.cn> Tue, 28 Nov 2023 16:52:06 +0800
libkysdk-base (2.3.0.0-0k0.4) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 上传libkysdk-conf2
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Mon, 27 Nov 2023 15:26:44 +0800
libkysdk-base (2.3.0.0-0k0.2) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 :解决i386动态库路径与加载路径不一致问题
-- szm-min <shaozhimin@kylinos.cn> Mon, 20 Nov 2023 09:39:22 +0800
libkysdk-base (2.3.0.0-0k0.1) nile; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 改动态库路径到对应的架构下
-- szm-min <shaozhimin@kylinos.cn> Fri, 20 Oct 2023 09:59:39 +0800
libkysdk-base (2.3.0.0-0k0.0) nile; urgency=medium
* BUG号 : 无
* 需求号 : 23985 SDK文档完善
* 其他修改 : 无
-- szm-min <shaozhimin@kylinos.cn> Fri, 20 Oct 2023 09:59:39 +0800
libkysdk-base (2.2.0.0-0k0.4) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 注释掉log模块的日志转储部分
解决安全扫描漏洞
-- szm-min <shaozhimin@kylinos.cn> Thu, 19 Oct 2023 17:18:40 +0800
libkysdk-base (2.2.0.0-0k0.3) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 添加 diagnostics 模块
-- szm-min <shaozhimin@kylinos.cn> Mon, 28 Aug 2023 09:59:47 +0800
libkysdk-base (2.2.0.0-0k0.2) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 去掉control文件中的libkysdk-diagnostics依赖
-- szm-min <shaozhimin@kylinos.cn> Fri, 04 Aug 2023 10:45:16 +0800
libkysdk-base (2.2.0.0-0k0.1) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 删除shlibs自动补全依赖
-- szm-min <shaozhimin@kylinos.cn> Thu, 13 Jul 2023 14:25:27 +0800
libkysdk-base (2.2.0.0-0k0.0) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : update changelog 2.2
-- szm-min <shaozhimin@kylinos.cn> Wed, 21 Jun 2023 10:03:19 +0800
libkysdk-base (2.0.0.0-0k0.6) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 : 修改control文件依赖版本
-- szm-min <shaozhimin@kylinos.cn> Tue, 20 Jun 2023 19:51:55 +0800
libkysdk-base (2.0.0.0-0k0.5) yangtze; urgency=medium
* BUG号 : 无
* 需求号 : 无
* 其他修改 :
-- szm-min <shaozhimin@kylinos.cn> Tue, 06 Jun 2023 15:30:08 +0800
libkysdk-base (1.2.0.5kylin1-ok1~0715) yangtze; urgency=medium
* 合并主线v1.2
* update v1.2
-- szm-min <shaozhimin@kylinos.cn> Fri, 15 Jul 2022 10:32:27 +0800
libkysdk-base (1.1.1kylin1-ok4~0627) yangtze; urgency=medium
* 修改为quilt格式
* openkylin 重新导入
* fix bug#125453,控制面板账户模块缺少"账户信息"设置项
-- Xie Wei <xiewei@kylinos.cn> Fri, 10 Jun 2022 19:35:33 +0800
libkysdk-base (1.1.1kylin1) yangtze; urgency=medium
* BUG号 : 119832
* 需求号 : 无
* 其他修改 :
* publish for v1.1 update
-- liuyunhe <liuyunhe@kylinos.cn> Tue, 17 May 2022 16:17:53 +0800

200
debian/control vendored Normal file
View File

@ -0,0 +1,200 @@
Source: libkysdk-base
Section: utils
Priority: optional
Maintainer: kylin <chenzhikai@kylinos.cn>
Build-Depends: debhelper-compat (= 12),
libc6-dev,
cmake,
libsystemd-dev,
libdbus-1-dev,
libssl-dev,
libgtk-3-dev,
libglib2.0-dev,
libsqlite3-dev
Standards-Version: 4.4.1
Homepage: http://gitlab2.kylin.com/kysdk/kysdk-base
Package: libkysdk-base
Architecture: any
Section: utils
Depends: libkysdk-timer (= ${binary:Version}),
libkysdk-log (= ${binary:Version}),
libkysdk-config (= ${binary:Version}),
libkysdk-utils (= ${binary:Version}),
libkysdk-diagnostics (= ${binary:Version}),
libkysdk-basecommon (= ${binary:Version}),
libkysdk-gsetting (= ${binary:Version})
Multi-Arch: same
Description: 麒麟开发者套件 - 基础层套件提供日志管理、消息通信、进程守护、线程管理、定时器、调试与埋点、配置文件、utils
Package: libkysdk-base-dev
Architecture: all
Section: utils
Depends: libkysdk-base (= ${binary:Version}),
libkysdk-timer-dev (= ${binary:Version}),
libkysdk-log-dev (= ${binary:Version}),
libkysdk-config-dev (= ${binary:Version}),
libkysdk-utils-dev (= ${binary:Version}),
libkysdk-diagnostics-dev (= ${binary:Version}),
libkysdk-gsetting-dev (= ${binary:Version})
Multi-Arch: foreign
Description: 麒麟开发者套件 - 基础层套件 - 开发库提供日志管理、消息通信、进程守护、线程管理、定时器、调试与埋点、配置文件、utils
Package: libkysdk-timer
Architecture: any
Section: utils
Depends: libkysdk-basecommon (>=1.2.0),
libkysdk-utils(>=1.2.0),
libc6
Multi-Arch: same
Description: 定制器模块库
Package: libkysdk-timer-dev
Architecture: all
Section: utils
Depends: libkysdk-utils-dev(>=1.2.0),
libkysdk-timer (= ${binary:Version}),
libkysdk-basecommon(>=1.2.0),
libc6
Multi-Arch: foreign
Description: 定时器模块 - 开发库
Package: libkysdk-log
Architecture: any
Section: utils
Depends: libkysdk-config(>=1.2.0),
logrotate,
libkysdk-basecommon(>=1.2.0),
libkysdk-utils(>=1.2.0),
dbus,
libc6,
libdbus-1-3,
libsystemd0
Multi-Arch: same
Description: 日志库
Package: libkysdk-basecommon
Architecture: any
Section: utils
Depends:
Multi-Arch: same
Description: kysdk-base层公用数据包
Package: libkysdk-log-dev
Architecture: all
Section: utils
Depends: libkysdk-log (= ${binary:Version}),
libkysdk-config-dev(>=1.2.0),
libkysdk-utils-dev(>=1.2.0),
libsystemd-dev
Multi-Arch: foreign
Description: 日志库 - 开发库
Package: libkysdk-config
Architecture: any
Section: utils
Depends: libkysdk-basecommon(>=1.2.0),
libkysdk-utils(>=1.2.0),
libc6
Multi-Arch: same
Description: 配置文件库
Package: libkysdk-config-dev
Architecture: all
Section: utils
Depends: libkysdk-utils-dev(>=1.2.0),
libkysdk-config (= ${binary:Version})
Multi-Arch: foreign
Description: 配置文件库 - 开发库
Package: libkysdk-utils
Architecture: any
Section: utils
Depends: libkysdk-basecommon(>=1.2.0),
libc6
Multi-Arch: same
Description: 开发者utils
Package: libkysdk-utils-dev
Architecture: all
Section: utils
Depends: libkysdk-utils (= ${binary:Version})
Multi-Arch: foreign
Description: 开发者utils - 开发库
Package: libkysdk-diagnostics
Architecture: any
Section: utils
Depends: libkysdk-basecommon(>=1.2.0),
libkysdk-utils(>=1.2.0),
libc6,
libdbus-1-3,
libgcc-s1 | libgcc1,
libssl1.1,
libstdc++6
Multi-Arch: same
Description: 开发者diagnostics
Package: libkysdk-diagnostics-dev
Architecture: all
Section: utils
Depends: libkysdk-diagnostics (= ${binary:Version})
Multi-Arch: foreign
Description: 开发者diagnostics - 开发库
Package: libkysdk-gsetting
Architecture: any
Section: utils
Depends: libgtk-3-0,
libglib2.0-0,
libkysdk-basecommon(>=1.2.0),
libatk1.0-0,
libc6,
libcairo-gobject2,
libcairo2,
libgdk-pixbuf2.0-0,
libharfbuzz0b,
libpango-1.0-0,
libpangocairo-1.0-0
Multi-Arch: same
Description: 开发者gsetting
Package: libkysdk-gsetting-dev
Architecture: all
Section: utils
Depends: libkysdk-gsetting (= ${binary:Version})
Multi-Arch: foreign
Description: 开发者gsetting - 开发库
Package: libkysdk-conf2
Architecture: any
Section: utils
Depends: libglib2.0-0,
libgtk-3-0,
libkysdk-basecommon(>=2.2.0),
libc6,
libsqlite3-0,
libkysdk-log,
python3.8,
python3-dbus,
python3-watchdog,
${misc:Depends},
${shlibs:Depends}
Multi-Arch: same
Description: 统一配置模块
Package: libkysdk-conf2-dev
Architecture: all
Section: utils
Depends: libkysdk-conf2 (= ${binary:Version})
Multi-Arch: foreign
Description: 统一配置模块 - 开发库
Package: libkysdk-conf2-tools
Architecture: any
Section: utils
Depends: libkysdk-conf2 (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Multi-Arch: same
Description: 统一配置模块 - 工具包

43
debian/copyright vendored Normal file
View File

@ -0,0 +1,43 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: kysdk-base
Upstream-Contact: <preferred name and address to reach the upstream project>
Source: <url://example.com>
Files: *
Copyright: <years> <put author's name and email here>
<years> <likewise for another author>
License: <special license>
<Put the license of the package here indented by 1 space>
<This follows the format of Description: lines in control file>
.
<Including paragraphs>
# If you want to use GPL v2 or later for the /debian/* files use
# the following clauses, or change it to suit. Delete these two lines
Files: debian/*
Copyright: 2021 kylin <chenzhikai@kylinos.cn>
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.
# Please avoid picking licenses with terms that are more restrictive than the
# packaged work, as it may make Debian's contributions unacceptable upstream.
#
# If you need, there are some extra license texts available in two places:
# /usr/share/debhelper/dh_make/licenses/
# /usr/share/common-licenses/

2
debian/gbp.conf vendored Normal file
View File

@ -0,0 +1,2 @@
[DEFAULT]
compression=xz

1
debian/libkysdk-base-dev.install vendored Normal file
View File

@ -0,0 +1 @@
development-files/kysdk-base.pc usr/share/pkgconfig/

1
debian/libkysdk-basecommon.install vendored Normal file
View File

@ -0,0 +1 @@
development-files/kysdk-base.conf etc/ld.so.conf.d

2
debian/libkysdk-conf2-dev.install vendored Normal file
View File

@ -0,0 +1,2 @@
src/conf2/api/libkysettings.h usr/include/kysdk/kysdk-base
development-files/kysdk-conf2.pc usr/share/pkgconfig/

3
debian/libkysdk-conf2-tools.install vendored Normal file
View File

@ -0,0 +1,3 @@
usr/bin/kconf2 usr/bin
usr/bin/kconf2-editor usr/bin
src/conf2/tools/gschema_xml2yaml.py usr/bin

12
debian/libkysdk-conf2.install vendored Normal file
View File

@ -0,0 +1,12 @@
usr/lib/*/libkyconf2.so*
src/conf2/service/conf2Utils.py usr/bin
src/conf2/service/conf2-server.py usr/bin
src/conf2/service/kysdk-conf2.conf etc/dbus-1/system.d
src/conf2/service/kysdk-conf2.service lib/systemd/system
src/conf2/service/com.kylin.kysdk.conf2.limit etc/dbus-1/conf
src/conf2/service/com.kylin.kysdk.conf2.limit usr/share/dbus-1/conf
src/conf2/service/com.kylin.kysdk.conf2.limit.verify etc/dbus-1/conf
src/conf2/service/com.kylin.kysdk.conf2.limit.verify usr/share/dbus-1/conf
src/conf2/service/conf2-session-server.py usr/bin
src/conf2/service/kysdk-conf2.desktop etc/xdg/autostart/
src/conf2/configs/conf2.yaml etc/kylin-config/

82
debian/libkysdk-conf2.symbols vendored Normal file
View File

@ -0,0 +1,82 @@
# SymbolsHelper-Confirmed: 2.4.1.0 amd64
libkyconf2.so.1 libkysdk-conf2 #MINVER#
app_data_destroy@Base 2.3.0.0
data_equal@Base 2.3.0.0
data_hash@Base 2.3.0.0
k_settings_get_type@Base 2.3.0.0
kdk_conf2_connect_signal@Base 2.3.0.0
kdk_conf2_get_boolean@Base 2.3.0.0
kdk_conf2_get_child@Base 2.3.0.0
kdk_conf2_get_default_boolean@Base 2.4.1.0
kdk_conf2_get_default_double@Base 2.4.1.0
kdk_conf2_get_default_enum@Base 2.4.1.0
kdk_conf2_get_default_int64@Base 2.4.1.0
kdk_conf2_get_default_int@Base 2.4.1.0
kdk_conf2_get_default_string@Base 2.4.1.0
kdk_conf2_get_default_strv@Base 2.4.1.0
kdk_conf2_get_default_uint64@Base 2.4.1.0
kdk_conf2_get_default_uint@Base 2.4.1.0
kdk_conf2_get_default_value@Base 2.3.0.0
kdk_conf2_get_descrition@Base 2.3.0.0
kdk_conf2_get_double@Base 2.3.0.0
kdk_conf2_get_enum@Base 2.3.0.0
kdk_conf2_get_id@Base 2.3.0.0
kdk_conf2_get_int64@Base 2.3.0.0
kdk_conf2_get_int@Base 2.3.0.0
kdk_conf2_get_range@Base 2.3.0.0
kdk_conf2_get_string@Base 2.3.0.0
kdk_conf2_get_strv@Base 2.3.0.0
kdk_conf2_get_summary@Base 2.3.0.0
kdk_conf2_get_type@Base 2.3.0.0
kdk_conf2_get_uint64@Base 2.3.0.0
kdk_conf2_get_uint@Base 2.3.0.0
kdk_conf2_get_value@Base 2.3.0.0
kdk_conf2_get_version@Base 2.3.0.0
kdk_conf2_has_key@Base 2.4.1.0
kdk_conf2_is_schema@Base 2.4.1.0
kdk_conf2_is_writable@Base 2.3.0.0
kdk_conf2_ksettings_destroy@Base 2.3.0.0
kdk_conf2_list_children@Base 2.3.0.0
kdk_conf2_list_keys@Base 2.3.0.0
kdk_conf2_list_schemas@Base 2.3.0.0
kdk_conf2_new@Base 2.3.0.0
kdk_conf2_new_extends_id@Base 2.4.1.0
kdk_conf2_range_check@Base 2.3.0.0
kdk_conf2_reload@Base 2.3.0.0
kdk_conf2_reset@Base 2.3.0.0
kdk_conf2_save_user_configure@Base 2.4.1.0
kdk_conf2_schema_destroy@Base 2.3.0.0
kdk_conf2_schema_find_child@Base 2.3.0.0
kdk_conf2_schema_get_id@Base 2.3.0.0
kdk_conf2_schema_get_key@Base 2.3.0.0
kdk_conf2_schema_get_version@Base 2.3.0.0
kdk_conf2_schema_has_key@Base 2.3.0.0
kdk_conf2_schema_key_get_default_value@Base 2.3.0.0
kdk_conf2_schema_key_get_description@Base 2.3.0.0
kdk_conf2_schema_key_get_name@Base 2.3.0.0
kdk_conf2_schema_key_get_permission@Base 2.3.0.0
kdk_conf2_schema_key_get_range@Base 2.3.0.0
kdk_conf2_schema_key_get_summary@Base 2.3.0.0
kdk_conf2_schema_key_get_value@Base 2.3.0.0
kdk_conf2_schema_key_range_check@Base 2.3.0.0
kdk_conf2_schema_key_value_type@Base 2.3.0.0
kdk_conf2_schema_list_children@Base 2.3.0.0
kdk_conf2_schema_list_keys@Base 2.3.0.0
kdk_conf2_schema_reload@Base 2.3.0.0
kdk_conf2_schema_table_lookup@Base 2.3.0.0
kdk_conf2_schema_update_schemas_table@Base 2.3.0.0
kdk_conf2_set_boolean@Base 2.3.0.0
kdk_conf2_set_double@Base 2.3.0.0
kdk_conf2_set_enum@Base 2.3.0.0
kdk_conf2_set_int64@Base 2.3.0.0
kdk_conf2_set_int@Base 2.3.0.0
kdk_conf2_set_string@Base 2.3.0.0
kdk_conf2_set_strv@Base 2.3.0.0
kdk_conf2_set_uint64@Base 2.3.0.0
kdk_conf2_set_uint@Base 2.3.0.0
kdk_conf2_set_value@Base 2.3.0.0
schema_data_destroy@Base 2.3.0.0
schemas_table@Base 2.3.0.0
version_data_destroy@Base 2.3.0.0
kdk_conf2_get_schema_summary@Base 2.5.1.0
kdk_conf2_get_schema_desription@Base 2.5.1.0

2
debian/libkysdk-config-dev.install vendored Normal file
View File

@ -0,0 +1,2 @@
src/config/libkyconf.h usr/include/kysdk/kysdk-base
development-files/kysdk-config.pc usr/share/pkgconfig/

8
debian/libkysdk-config-dev.manpages vendored Normal file
View File

@ -0,0 +1,8 @@
man/config/kdk_conf_destroy.3
man/config/kdk_conf_get_value.3
man/config/kdk_conf_init.3
man/config/kdk_conf_list_group.3
man/config/kdk_conf_list_key.3
man/config/kdk_conf_reload.3
man/config/kdk_config_freeall.3
man/config/libkyconf.3

1
debian/libkysdk-config.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/libkyconf.so*

27
debian/libkysdk-config.symbols vendored Normal file
View File

@ -0,0 +1,27 @@
# SymbolsHelper-Confirmed: 2.0.0.0 amd64
libkyconf.so.1 libkysdk-cofig #MINVER#
S_destroyParse@Base 1.1.1
S_getGroupList@Base 1.1.1
S_getKeyList@Base 1.1.1
S_getValue@Base 1.1.1
S_newParse@Base 1.1.1
S_parseFile@Base 1.1.1
S_setAssignmentDelimiter@Base 1.1.1
S_setKeyDelimiter@Base 1.1.1
S_setValue@Base 1.1.1
S_setValueDelimiter@Base 1.1.1
S_write2File@Base 1.1.1
S_writeBack@Base 1.1.1
isgsettings@Base 1.1.1
isjson@Base 1.1.1
isxml@Base 1.1.1
kdk_conf_destroy@Base 1.1.1
kdk_conf_disable_autoreload@Base 1.1.1
kdk_conf_enable_autoreload@Base 1.1.1
kdk_conf_get_value@Base 1.1.1
kdk_conf_init@Base 1.1.1
kdk_conf_list_group@Base 1.1.1
kdk_conf_list_key@Base 1.1.1
kdk_conf_reload@Base 1.1.1
kdk_conf_set_value@Base 1.1.1
kdk_config_freeall@Base 2.0.0.0

View File

@ -0,0 +1,2 @@
src/diagnostics/libkydiagnostics.h usr/include/kysdk/kysdk-base
development-files/kysdk-diagnostics.pc usr/share/pkgconfig/

View File

@ -0,0 +1,2 @@
man/diagnostics/kdk_buried_point.3
man/diagnostics/libkydiagnostics.3

1
debian/libkysdk-diagnostics.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/libkydiagnostics.so*

3
debian/libkysdk-diagnostics.symbols vendored Normal file
View File

@ -0,0 +1,3 @@
# SymbolsHelper-Confirmed: 2.2.0.0 amd64
libkydiagnostics.so.1 libkysdk-diagnostics #MINVER#
kdk_buried_point@Base 2.2.0.0

2
debian/libkysdk-gsetting-dev.install vendored Normal file
View File

@ -0,0 +1,2 @@
src/gsettings/libkygsetting.h usr/include/kysdk/kysdk-base
development-files/kysdk-gsetting.pc usr/share/pkgconfig/

9
debian/libkysdk-gsetting-dev.manpages vendored Normal file
View File

@ -0,0 +1,9 @@
man/gsettings/kdk_gsettings_get.3
man/gsettings/kdk_gsettings_set.3
man/gsettings/kdk_settings_get_double.3
man/gsettings/kdk_settings_get_int.3
man/gsettings/kdk_settings_get_string.3
man/gsettings/kdk_settings_reset.3
man/gsettings/kdk_settings_set_int.3
man/gsettings/kdk_settings_set_string.3
man/gsettings/libkygsetting.3

1
debian/libkysdk-gsetting.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/libkygsetting.so*

11
debian/libkysdk-gsetting.symbols vendored Normal file
View File

@ -0,0 +1,11 @@
# SymbolsHelper-Confirmed: 2.0.0.0 amd64
libkygsetting.so.1 libkysdk-gsetting #MINVER#
kdk_gsettings_get@Base 2.0.0.0
kdk_gsettings_set@Base 2.0.0.0
kdk_settings_get_double@Base 2.0.0.0
kdk_settings_get_int@Base 2.0.0.0
kdk_settings_get_string@Base 2.0.0.0
kdk_settings_reset@Base 2.0.0.0
kdk_settings_set_int@Base 2.0.0.0
kdk_settings_set_string@Base 2.0.0.0
schema_key_is_exist@Base 2.0.0.0

2
debian/libkysdk-log-dev.install vendored Normal file
View File

@ -0,0 +1,2 @@
src/log/libkylog.h usr/include/kysdk/kysdk-base
development-files/kysdk-log.pc usr/share/pkgconfig/

5
debian/libkysdk-log-dev.manpages vendored Normal file
View File

@ -0,0 +1,5 @@
man/log/kdk_logger_flush.3
man/log/kdk_logger_init.3
man/log/kdk_logger_set_autowrap.3
man/log/kdk_logger_setdir.3
man/log/libkylog.3

4
debian/libkysdk-log.install vendored Normal file
View File

@ -0,0 +1,4 @@
usr/lib/*/libkylog.so*
src/log/kylog-default.conf etc/kysdk/kysdk-base
src/log/kylog-rotate-default etc/kysdk/kysdk-base
#src/log/logrotate.cron etc/kysdk/kysdk-base

29
debian/libkysdk-log.symbols vendored Normal file
View File

@ -0,0 +1,29 @@
# SymbolsHelper-Confirmed: 1.1.1 amd64
libkylog.so.1 libkysdk-log #MINVER#
append_wrap@Base 1.1.1
destroyKLogger@Base 1.1.1
destroyMessageQueue@Base 1.1.1
emptyMessageQueue@Base 1.1.1
flushMessageQueue@Base 1.1.1
formatMessage@Base 1.1.1
getRecordDate@Base 1.1.1
initKLogger@Base 1.1.1
initMessageQueue@Base 1.1.1
insertMessage@Base 1.1.1
kdk_logger_flush@Base 1.1.1
kdk_logger_init@Base 1.1.1
kdk_logger_set_autowrap@Base 1.1.1
kdk_logger_setdir@Base 1.1.1
kdk_logger_write@Base 1.1.1
klog_printformat@Base 1.1.1
klog_rotate_init@Base 1.1.1
loadFormatOptions@Base 1.1.1
logger@Base 1.1.1
recycle@Base 1.1.1
setRootDir@Base 1.1.1
set_autowrap@Base 1.1.1
startMQDaemon@Base 1.1.1
stringLType@Base 1.1.1
stringLevel@Base 1.1.1
writeFile@Base 1.1.1
writeLog@Base 1.1.1

2
debian/libkysdk-timer-dev.install vendored Normal file
View File

@ -0,0 +1,2 @@
src/timer/libkytimer.h usr/include/kysdk/kysdk-base
development-files/kysdk-timer.pc usr/share/pkgconfig/

6
debian/libkysdk-timer-dev.manpages vendored Normal file
View File

@ -0,0 +1,6 @@
man/timer/kdk_timer_destroy.3
man/timer/kdk_timer_init.3
man/timer/kdk_timer_reset.3
man/timer/kdk_timer_start.3
man/timer/kdk_timer_stop.3
man/timer/libkytimer.3

1
debian/libkysdk-timer.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/*/libkytimer.so*

7
debian/libkysdk-timer.symbols vendored Normal file
View File

@ -0,0 +1,7 @@
# SymbolsHelper-Confirmed: 1.1.1 amd64
libkytimer.so.1 libkysdk-timer #MINVER#
kdk_timer_destroy@Base 1.1.1
kdk_timer_init@Base 1.1.1
kdk_timer_reset@Base 1.1.1
kdk_timer_start@Base 1.1.1
kdk_timer_stop@Base 1.1.1

7
debian/libkysdk-utils-dev.install vendored Normal file
View File

@ -0,0 +1,7 @@
src/utils/sdkmarcos.h usr/include/kysdk/kysdk-base
src/utils/kerr.h usr/include/kysdk/kysdk-base
src/utils/cstring-extension.h usr/include/kysdk/kysdk-base
src/utils/kyutils.h usr/include/kysdk/kysdk-base
src/utils/data-structure/linklist/skip_linklist/skip_linklist.h usr/include/kysdk/kysdk-base
src/utils/data-structure/linklist/listdata.h usr/include/kysdk/kysdk-base
development-files/kysdk-utils.pc usr/share/pkgconfig/

24
debian/libkysdk-utils-dev.manpages vendored Normal file
View File

@ -0,0 +1,24 @@
man/utils/kdkVolumeBaseCharacterConvert.3
man/utils/kdkVolumeBaseNumericalConvert.3
man/utils/kysdk_create_skiplist.3
man/utils/kysdk_destroy_skiplist.3
man/utils/kysdk_skiplist_delete.3
man/utils/kysdk_skiplist_insert.3
man/utils/kysdk_skiplist_search.3
man/utils/kysdk_skiplist_setmaxlevels.3
man/utils/libkydatastruct.3
man/utils/libkyutils.3
man/utils/str2lower.3
man/utils/str2upper.3
man/utils/strcounts.3
man/utils/strendwith.3
man/utils/strfirstof.3
man/utils/strlastof.3
man/utils/strskipblank.3
man/utils/strskipspace.3
man/utils/strsplit.3
man/utils/strstartswith_nocase.3
man/utils/strstartswith.3
man/utils/strstrip.3
man/utils/strstripblank.3
man/utils/strstripspace.3

2
debian/libkysdk-utils.install vendored Normal file
View File

@ -0,0 +1,2 @@
usr/lib/*/libkydatastruct.so*
usr/lib/*/libkyutils.so*

13
debian/libkysdk-utils.symbols vendored Normal file
View File

@ -0,0 +1,13 @@
# SymbolsHelper-Confirmed: 1.2.0.5 amd64
libkydatastruct.so.1 libkysdk-utils #MINVER#
kysdk_create_skiplist@Base 1.1.1
kysdk_destroy_skiplist@Base 1.1.1
kysdk_skiplist_delete@Base 1.1.1
kysdk_skiplist_insert@Base 1.1.1
kysdk_skiplist_search@Base 1.1.1
kysdk_skiplist_setmaxlevels@Base 1.1.1
libkyutils.so.1 libkysdk-utils #MINVER#
kdkVolumeBaseCharacterConvert@Base 1.2.0.5
kdkVolumeBaseNumericalConvert@Base 1.2.0.5
parse_size@Base 1.2.0.5
size_to_human_string@Base 1.2.0.5

25
debian/rules vendored Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#export DH_VERBOSE = 1
# see FEATURE AREAS in dpkg-buildflags(1)
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@
# dh_make generated override targets
# This is example for Cmake (See https://bugs.debian.org/641051 )
#override_dh_auto_configure:
# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (native)

View File

@ -1,6 +1,6 @@
base_version=2.3.0.0
base_version=2.5.0
Name: libkysdk-base
Description: kysdk base layer
Requires: kysdk-log >= ${base_version} kysdk-config >= ${base_version} kysdk-timer >= ${base_version} kysdk-utils >= ${base_version}
Version: 2.3.0.0
Version: 2.5.0

View File

@ -1,5 +1,5 @@
Name: libkysdk-conf2
Description: kysdk base conf2
Version: 2.3.0.0
Version: 2.5.0
Cflags: -I/usr/include/kysdk/kysdk-base/
Libs: -lkyconf2

View File

@ -1,8 +1,8 @@
base_version=2.3.0.0
base_version=2.4.0
Name: libkysdk-config
Description: kysdk base layer config component
Requires: kysdk-utils
Version: 2.3.0.0
Version: 2.5.0
Cflags: -I/usr/include/kysdk/kysdk-base/
Libs: -lkysdk-config
Libs: -lkyconf

View File

@ -1,5 +1,5 @@
Name: libkysdk-diagnostics
Description: kysdk base layer diagnostics component
Version: 2.3.0.0
Version: 2.5.0
Cflags: -I/usr/include/kysdk/kysdk-base/
Libs: -lkydiagnostics

View File

@ -1,6 +1,6 @@
Name: libkysdk-gsetting
Description: kysdk base layer gsettings component
Requires: gtk+-3.0 glib-2.0
Version: 2.3.0.0
Libs: -lkysdk-gsetting
Cflags: -I/usr/include/kysdk/kysdk-base/
Version: 2.5.0
Libs: -lkygsetting
Cflags: -I/usr/include/kysdk/kysdk-base/

View File

@ -1,6 +1,6 @@
Name: libkysdk-log
Description: kysdk base layer log component
Requires: kysdk-config kysdk-utils libsystemd
Version: 2.3.0.0
Version: 2.5.0
Cflags: -I/usr/include/kysdk/kysdk-base/
Libs: -lkysdk-log
Libs: -lkylog

View File

@ -1,6 +1,6 @@
Name: libkysdk-timer
Description: kysdk base layer time component
Requires: kysdk-utils
Version: 2.3.0.0
Version: 2.5.0
Cflags: -I/usr/include/kysdk/kysdk-base/
Libs: -lkysdk-timer
Libs: -lkytimer

View File

@ -1,5 +1,5 @@
Name: libkysdk-utils
Description: kysdk base layer utils component
Version: 2.3.0.0
Version: 2.5.0
Cflags:-I/usr/include/kysdk/kysdk-base/
Libs: -lkydatastruct -lkyutils
Libs: -lkydatastruct -lkyutils

View File

@ -3,6 +3,7 @@ include_directories(utils)
include_directories(log)
include_directories(timer)
include_directories(gsettings)
include_directories(conf2)
# add_subdirectory(communication)
add_subdirectory(config)

View File

@ -1,2 +0,0 @@
*.pro*
main.cpp

View File

@ -12,8 +12,14 @@ target_link_libraries(kconf2 kyconf2)
add_executable(kconf2-editor tools/kconf2-editor.c )
target_link_libraries(kconf2-editor kyconf2 ${GTK_LIBRARIES})
add_executable(kyconf2-test test/kyconf2-test.c)
target_link_libraries(kyconf2-test kyconf2)
install(TARGETS kconf2
DESTINATION /usr/bin)
install(TARGETS kconf2-editor
DESTINATION /usr/bin)
DESTINATION /usr/bin)
install(TARGETS kyconf2-test
DESTINATION /usr/bin)

View File

@ -1,8 +1,8 @@
# aux_source_directory(. SOURCESCODE)
add_library(kyconf2 SHARED libkysettings.c ksettingsschema.c )
set_target_properties(kyconf2 PROPERTIES VERSION 2.0.0 SOVERSION 1)
target_link_libraries(kyconf2 ${GLIB_LIBRARIES} ${GIO_LIBRARIES} -lsqlite3)
set_target_properties(kyconf2 PROPERTIES VERSION 2.5.0 SOVERSION 1)
target_link_libraries(kyconf2 ${GLIB_LIBRARIES} ${GIO_LIBRARIES} -lsqlite3 kylog)
# GNU
include(GNUInstallDirs)

View File

@ -25,7 +25,9 @@
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <syslog.h>
#include <pwd.h>
#include "libkylog.h"
/**
* @brief
@ -73,6 +75,10 @@ void schema_data_destroy(gpointer data)
KSettingsSchema *schema = (KSettingsSchema *)data;
g_free(schema->id);
g_free(schema->version);
g_free(schema->permission);
g_free(schema->description);
g_free(schema->summary);
g_free(schema->extends);
if (schema->values)
{
g_hash_table_destroy(schema->values);
@ -153,7 +159,6 @@ static int _sql_call_get_lines(void *data, int argc, char **argv, char **azColNa
char **columns = calloc(argc + 1, sizeof(char *));
for (int i = 0; i < argc; i++)
{
char *fewf = argv[i];
columns[i] = g_strdup(argv[i]);
}
char ***tmp = realloc(lines, sizeof(char **) * (line_count + 2));
@ -184,7 +189,18 @@ static int _sql_call_get_schema(void *data, int argc, char **argv, char **azColN
{
KSettingsSchema *schema = (KSettingsSchema *)data;
if (NULL == argv[3])
char *node_name = argv[2];
char *node_type = argv[3];
char *permission = argv[4];
char *description = argv[5];
char *summary = argv[6];
char *value_type = argv[8];
char *custom_value = argv[9];
char *default_value = argv[10];
char *value_range = argv[11];
char *extends = argv[12];
if (0 == strcmp(node_type, "key"))
{
// hash表 shashs:s
if (NULL == schema->values)
@ -193,31 +209,32 @@ static int _sql_call_get_schema(void *data, int argc, char **argv, char **azColN
GHashTable *item = g_hash_table_new(g_str_hash, g_str_equal);
if (NULL == item)
goto err;
if (argv[2])
g_hash_table_insert(item, "property", g_strdup(argv[2])); // 键名
if (argv[4])
g_hash_table_insert(item, "user_value", g_strdup(argv[4])); // 键值
if (argv[5])
g_hash_table_insert(item, "data_type", g_strdup(argv[5])); // 类型
if (argv[6])
g_hash_table_insert(item, "default_value", g_strdup(argv[6])); // 默认值
if (argv[7])
g_hash_table_insert(item, "permission", g_strdup(argv[7])); // 读写权限
if (argv[8])
g_hash_table_insert(item, "range", g_strdup(argv[8])); // 取值范围
if (argv[10])
g_hash_table_insert(item, "description", g_strdup(argv[10])); // 详细描述
if (argv[11])
g_hash_table_insert(item, "summary", g_strdup(argv[11])); // 概要
g_hash_table_insert(schema->values, g_strdup(argv[2]), item);
if (node_name)
g_hash_table_insert(item, "node_name", g_strdup(node_name)); // 键名
if (permission)
g_hash_table_insert(item, "permission", g_strdup(permission)); // 读写权限
if (description)
g_hash_table_insert(item, "description", g_strdup(description)); // 详细描述
if (summary)
g_hash_table_insert(item, "summary", g_strdup(summary)); // 概要
if (value_type)
g_hash_table_insert(item, "value_type", g_strdup(value_type)); // 类型
if (custom_value)
g_hash_table_insert(item, "custom_value", g_strdup(custom_value)); // 键值
if (default_value)
g_hash_table_insert(item, "default_value", g_strdup(default_value)); // 默认值
if (value_range)
g_hash_table_insert(item, "range", g_strdup(value_range)); // 取值范围
g_hash_table_insert(schema->values, g_strdup(node_name), item);
}
else
else if (0 == strcmp(node_type, "schema"))
{
if (NULL == schema->children)
{
schema->children = g_array_new(FALSE, FALSE, sizeof(char *));
}
char *tmp = g_strdup(argv[3]);
char *tmp = g_strdup(node_name);
g_array_append_val(schema->children, tmp);
}
return 0;
@ -231,17 +248,28 @@ err:
// 读取一个组件
static KSettingsSchema *_get_schema(const char *id, const char *version)
{
char *user_name = getlogin();
if (user_name == NULL)
return NULL;
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
strcpy(user_name, "root");
}
else
{
strcpy(user_name, pw->pw_name);
endpwent();
}
KSettingsSchema *schema = NULL;
char db_file[PATH_MAX];
if (0 == strcmp(user_name, "root"))
sprintf(db_file, "/etc/kylin-config/kylin-config/user.db");
sprintf(db_file, "/root/.config/kylin-config/user.db");
else
sprintf(db_file, "/home/%s/.config/kylin-config/user.db", user_name);
// syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s \n", __func__, db_file);
char **id_list = _split_string(id, '.');
if (!id_list)
@ -251,27 +279,40 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
sqlite3 *db = NULL;
char *err_msg = NULL;
// 打开数据库
int rc = sqlite3_open(db_file, &db);
if (rc != SQLITE_OK)
{
rc = sqlite3_open("/etc/kylin-config/kylin-config/user.db", &db);
if (rc != SQLITE_OK)
if (0 == strcmp(db_file, "/root/.config/kylin-config/user.db"))
{
fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
goto out;
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed! %s try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
if (rc != SQLITE_OK)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open /etc/kylin-config/user.db failed. %s\n", __func__, sqlite3_errmsg(db));
g_strfreev(id_list);
return NULL;
}
}
else
return NULL;
}
rc = sqlite3_exec(db, "BEGIN TRANSACTION", 0, 0, &err_msg);
if (rc != SQLITE_OK)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法开始事务: %s\n", __func__, err_msg);
goto out;
}
// 查询数据
int app_id = 0, version_id = 0, parent_id = 0;
char sql[100];
char sql[1024];
sprintf(sql, "SELECT * FROM app WHERE app_name = '%s'", id_list[0]);
char **columns = NULL;
rc = sqlite3_exec(db, sql, _sql_call_get_columns, &columns, &err_msg);
if (rc != SQLITE_OK || NULL == columns)
{
fprintf(stderr, "查询失败: %s\n", err_msg);
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询应用%s失败: %s\n", __func__, id_list[0], err_msg);
goto out;
}
app_id = atoi(columns[0]);
@ -283,8 +324,7 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
rc = sqlite3_exec(db, sql, _sql_call_get_columns, &columns, &err_msg);
if (rc != SQLITE_OK)
{
// TODO: 版本兼容性处理
fprintf(stderr, "查询失败: %s\n", err_msg);
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询%s版本号%s失败: %s\n", __func__, version, err_msg);
goto out;
}
version_id = atoi(columns[0]);
@ -293,13 +333,13 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
int i = 1;
while (id_list[i])
{
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d AND group_name = '%s'",
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d AND node_name = '%s' AND node_type = 'schema'",
version_id, parent_id, id_list[i++]);
rc = sqlite3_exec(db, sql, _sql_call_get_columns, &columns, &err_msg);
if (rc != SQLITE_OK)
{
fprintf(stderr, "查询失败: %s\n", err_msg);
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询组件%s失败: %s\n", __func__, id_list[i], err_msg);
goto out;
}
parent_id = atoi(columns[0]);
@ -316,113 +356,44 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
rc = sqlite3_exec(db, sql, _sql_call_get_schema, schema, &err_msg);
if (rc != SQLITE_OK)
{
fprintf(stderr, "查询失败: %s\n", err_msg);
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询失败: %s\n", __func__, err_msg);
goto out;
}
out:
rc = sqlite3_exec(db, "COMMIT", NULL, NULL, &err_msg);
if (rc != SQLITE_OK)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法提交事务: %s\n", __func__, err_msg);
goto out;
}
sqlite3_close(db);
g_strfreev(id_list);
return schema;
out:
sqlite3_exec(db, "ROLLBACK", 0, 0, &err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
g_strfreev(id_list);
if (err_msg)
sqlite3_free(err_msg);
if (db)
sqlite3_close(db);
return schema;
}
// 递归读取组件配置
static int _get_component_recursively(char *version, int version_id, int parent_id, char *parent_name, GHashTable *schemas, sqlite3 *db)
static void _get_schemas()
{
char *err_msg = NULL;
char sql[128];
char ***components = NULL;
line_count = 0;
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d AND group_name IS NOT NULL", version_id, parent_id);
int rc = sqlite3_exec(db, sql, _sql_call_get_lines, &components, &err_msg);
if (rc != SQLITE_OK)
{
fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
return rc;
}
char ***apps = NULL, ***versions = NULL, ***configures = NULL;
KSettingsSchema *schema = g_hash_table_lookup(schemas, parent_name);
if (NULL == schema)
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
schema = calloc(1, sizeof *schema);
if (NULL == schema)
return SQLITE_NOMEM;
schema->id = strdup(parent_name);
schema->version = strdup(version);
g_hash_table_insert(schemas, strdup(parent_name), schema);
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
strcpy(user_name, "root");
}
else
{
if (schema->values)
{
g_hash_table_destroy(schema->values);
schema->values = NULL;
}
if (schema->children)
{
g_array_free(schema->children, TRUE);
schema->children = NULL;
}
}
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d",
version_id, parent_id);
rc = sqlite3_exec(db, sql, _sql_call_get_schema, schema, &err_msg);
if (rc != SQLITE_OK)
{
fprintf(stderr, "查询失败: %s\n", err_msg);
// schema_data_destroy(schema);
return rc;
}
// components为空
if (NULL == components)
{
return rc;
}
for (int i = 0; components[i]; i++)
{
parent_id = atoi(components[i][0]);
char *id = g_strdup_printf("%s.%s", parent_name, components[i][3]);
// 递归读取
rc = _get_component_recursively(version, version_id, parent_id, id, schemas, db);
if (rc != SQLITE_OK)
{
for (int j = 0; components[j]; j++)
{
for (int k = 0; k < 12; k++)
free(components[j][k]);
free(components[j]);
}
free(components);
return rc;
}
}
for (int j = 0; components[j]; j++)
{
for (int k = 0; k < 12; k++)
free(components[j][k]);
free(components[j]);
}
free(components);
return rc;
}
// 读取所有组件配置
static void _get_schemas()
{
char *user_name = getlogin();
if (user_name == NULL)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Get user name failed! use root config");
closelog();
user_name = "root";
strcpy(user_name, pw->pw_name);
endpwent();
}
char db_file[PATH_MAX];
@ -430,6 +401,7 @@ static void _get_schemas()
sprintf(db_file, "/root/.config/kylin-config/user.db");
else
sprintf(db_file, "/home/%s/.config/kylin-config/user.db", user_name);
// syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s \n", __func__, db_file);
// 读取数据库数据
sqlite3 *db = NULL;
@ -439,167 +411,352 @@ static void _get_schemas()
int rc = sqlite3_open(db_file, &db);
if (rc != SQLITE_OK)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "open %s failed with error code %d! try to open /etc/kylin-config/user.db.", db_file, rc);
closelog();
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
if (rc != SQLITE_OK)
if (0 == strcmp(db_file, "/root/.config/kylin-config/user.db"))
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "open /etc/kylin-config/user.db failed with error code %d", rc);
closelog();
goto out;
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed! %s try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
if (rc != SQLITE_OK)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open /etc/kylin-config/user.db failed. %s\n", __func__, sqlite3_errmsg(db));
return;
}
}
else
return;
}
// 顶层hash 元素为appData:hash(versionData:hash(s:KSettingsSchema))
if (NULL == schemas_table)
schemas_table = g_hash_table_new_full(data_hash, data_equal, app_data_destroy, (GDestroyNotify)g_hash_table_destroy);
if (NULL == schemas_table)
char sql[100];
rc = sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &err_msg);
if (rc != SQLITE_OK)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Creat hash Table failed");
closelog();
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法开始事务: %s\n", __func__, err_msg);
goto out;
}
int i = 0;
char sql[100];
char ***apps = NULL;
strcpy(sql, "SELECT * FROM app");
line_count = 0;
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &apps, &err_msg);
if (rc != SQLITE_OK)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "查询失败: %s\n", err_msg);
closelog();
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询应用名失败: %s\n", __func__, err_msg);
goto out;
}
while (apps && apps[i])
line_count = 0;
sprintf(sql, "SELECT * FROM version");
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &versions, &err_msg);
if (rc != SQLITE_OK)
{
char ***versions = NULL;
int app_id = atoi(apps[i][0]);
AppData *app_data = calloc(1, sizeof *app_data);
app_data->name = strdup(apps[i][1]);
app_data->default_version = strdup(apps[i][2]);
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询版本号失败: %s\n", __func__, err_msg);
goto out;
}
line_count = 0;
sprintf(sql, "SELECT * FROM version WHERE app_id = %d", app_id);
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &versions, &err_msg);
if (rc != SQLITE_OK)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "查询失败: %s\n", err_msg);
closelog();
for (int j = 0; apps[j]; j++)
{
for (int k = 0; k < 3; k++)
free(apps[j][k]);
free(apps[j]);
}
free(apps);
goto out;
}
// 第二层hash元素为versionData:hash(s:KSettingsSchema)
GHashTable *version = g_hash_table_lookup(schemas_table, app_data);
if (NULL == version)
{
version = g_hash_table_new_full(data_hash, data_equal, version_data_destroy, (GDestroyNotify)g_hash_table_destroy);
if (NULL == version)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Creat hash2 Table failed");
closelog();
goto out;
}
g_hash_table_insert(schemas_table, app_data, version);
}
else
app_data_destroy(app_data);
line_count = 0;
strcpy(sql, "SELECT * FROM configures");
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &configures, &err_msg);
if (rc != SQLITE_OK)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :读取组件所有配置失败: %s\n", __func__, err_msg);
goto out;
}
int version_i = 0;
while (versions[version_i])
rc = sqlite3_exec(db, "COMMIT", NULL, NULL, &err_msg);
if (rc != SQLITE_OK)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法提交事务: %s\n", __func__, err_msg);
goto out;
}
sqlite3_close(db);
if (!apps || !versions || ! configures)
return;
// 顶层hash 元素为appData:hash(versionData:hash(s:KSettingsSchema))
if (NULL == schemas_table)
schemas_table = g_hash_table_new_full(data_hash, data_equal, app_data_destroy, (GDestroyNotify)g_hash_table_destroy);
if (NULL == schemas_table)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat hash Table failed\n", __func__);
goto out;
}
int app_id = 0, version_id = 0;
GHashTable *version = NULL;
GHashTable *schemas = NULL;
KSettingsSchema *schema = NULL;
char curr_id[512] = {0};
#define APP_COLUMN apps[app_id - 1]
#define VER_COLUMN versions[version_id - 1]
// 遍历配置
for (int i = 0; configures[i]; i++)
{
// 版本id改变
if (version_id != atoi(configures[i][1]))
{
int version_id = atoi(versions[version_i][0]);
VersionData *version_data = calloc(1, sizeof *version_data);
version_data->name = strdup(versions[version_i][2]);
version_data->compatible = _split_string(versions[version_i][3], '.');
// 第三层hash元素为s:KSettingsSchema
GHashTable *schemas = g_hash_table_lookup(version, version_data);
AppData *app_data = NULL;
VersionData *version_data = NULL;
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read a new version id %s, old id is %d\n", __func__, configures[i][1], version_id);
version_id = atoi(configures[i][1]);
version_data = calloc(1, sizeof *version_data);
version_data->name = strdup(VER_COLUMN[2]);
version_data->compatible = _split_string(VER_COLUMN[3], '.');
// 版本id对应的应用id改变
if (app_id != atoi(VER_COLUMN[1]))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read a new app id %s, old id is %d\n", __func__, VER_COLUMN[1], app_id);
app_id = atoi(VER_COLUMN[1]);
app_data = calloc(1, sizeof *app_data);
app_data->name = strdup(APP_COLUMN[1]);
app_data->default_version = strdup(APP_COLUMN[2]);
version = g_hash_table_lookup(schemas_table, app_data);
if (NULL == version)
{
version = g_hash_table_new_full(data_hash, data_equal, version_data_destroy, (GDestroyNotify)g_hash_table_destroy);
if (NULL == version)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat hash2 Table failed\n", __func__);
app_data_destroy(app_data);
version_data_destroy(version_data);
goto out;
}
g_hash_table_insert(schemas_table, app_data, version);
}
else
app_data_destroy(app_data);
}
schemas = g_hash_table_lookup(version, version_data);
if (NULL == schemas)
{
schemas = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)schema_data_destroy);
g_hash_table_insert(version, version_data, schemas);
if (NULL == schemas)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Creat schemas hash Table failed");
closelog();
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat schemas hash Table failed\n", __func__);
version_data_destroy(version_data);
goto out;
}
}
else
version_data_destroy(version_data);
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read %s configure wiht version number %s\n", __func__, APP_COLUMN[1], VER_COLUMN[2]);
rc = _get_component_recursively(versions[version_i][2], version_id, 0, apps[i][1], schemas, db);
if (rc != SQLITE_OK)
schema = g_hash_table_lookup(schemas, APP_COLUMN[1]);
if (NULL == schema)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Read data failed");
closelog();
for (int j = 0; j < i + 1; j++)
syslog(LOG_INFO, "[kysdk-conf2] %s -> Creat node %s\n", __func__, APP_COLUMN[1]);
schema = calloc(1, sizeof *schema);
if (NULL == schema)
goto out;
schema->id = strdup(APP_COLUMN[1]);
schema->version = strdup(VER_COLUMN[2]);
g_hash_table_insert(schemas, strdup(APP_COLUMN[1]), schema);
}
else
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
if (schema->values)
{
for (int k = 0; k < 3; k++)
free(apps[j][k]);
free(apps[j]);
g_hash_table_destroy(schema->values);
schema->values = NULL;
}
free(apps);
for (int j = 0; versions[j]; j++)
if (schema->children)
{
for (int k = 0; k < 4; k++)
free(versions[j][k]);
free(versions[j]);
g_array_free(schema->children, TRUE);
schema->children = NULL;
}
free(versions);
}
}
char *node_name = configures[i][2];
char *node_type = configures[i][3];
char *permission = configures[i][4];
char *description = configures[i][5];
char *summary = configures[i][6];
char *value_type = configures[i][8];
char *custom_value = configures[i][9];
char *default_value = configures[i][10];
char *value_range = configures[i][11];
char *extends = configures[i][12];
// 一个新的组件
if (0 == strcmp(node_type, "schema"))
{
int parent_id = atoi(configures[i][7]);
char parent_name[512], tmp[512];
memset(parent_name, 0, 512);
memset(tmp, 0, 512);
if (0 == parent_id)
{
strcpy(parent_name, APP_COLUMN[1]);
}
else
{
while (0 != parent_id)
{
strcat(tmp, ".");
strcat(tmp, configures[parent_id - 1][2]);
parent_id = atoi(configures[parent_id - 1][7]);
}
sprintf(parent_name, "%s%s", APP_COLUMN[1], tmp);
}
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s's parent name %s\n", __func__, node_name, parent_name);
// 给父组件增加子组件名
KSettingsSchema *parent_schema = g_hash_table_lookup(schemas, parent_name);
if (NULL != parent_schema)
{
if (NULL == parent_schema->children)
{
parent_schema->children = g_array_new(FALSE, FALSE, sizeof(char *));
}
char *tmp = g_strdup(node_name);
g_array_append_val(parent_schema->children, tmp);
}
char schema_name[512];
memset(schema_name, 0, 512);
sprintf(schema_name, "%s.%s", parent_name, node_name);
schema = g_hash_table_lookup(schemas, schema_name);
if (NULL == schema)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Creat node %s\n", __func__, schema_name);
schema = calloc(1, sizeof *schema);
if (NULL == schema)
{
goto out;
syslog(LOG_ERR, "[kysdk-conf2] %s -> Creat HashTable fail\n", __func__);
}
schema->id = strdup(schema_name);
schema->version = strdup(VER_COLUMN[2]);
if (permission)
schema->permission = strdup(permission);
if (description)
schema->description = strdup(description);
if (summary)
schema->summary = strdup(summary);
if (extends)
schema->extends = strdup(extends);
g_hash_table_insert(schemas, strdup(schema_name), schema);
}
else
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
if (schema->values)
{
g_hash_table_destroy(schema->values);
schema->values = NULL;
}
if (schema->children)
{
g_array_free(schema->children, TRUE);
schema->children = NULL;
}
g_free(schema->permission);
g_free(schema->description);
g_free(schema->summary);
g_free(schema->extends);
if (permission)
schema->permission = strdup(permission);
if (description)
schema->description = strdup(description);
if (summary)
schema->summary = strdup(summary);
if (extends)
schema->extends = strdup(extends);
}
}
else if (0 == strcmp(node_type, "key"))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read %s configure wiht version number %s\n", __func__, schema->id, VER_COLUMN[2]);
// hash表 shashs:s
if (NULL == schema->values)
schema->values = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy);
// hash表 s:s
GHashTable *item = g_hash_table_new(g_str_hash, g_str_equal);
if (NULL == item)
{
syslog(LOG_ERR, "[kysdk-conf2] %s -> Memary error\n", __func__);
goto out;
}
version_i++;
if (node_name)
g_hash_table_insert(item, "node_name", g_strdup(node_name)); // 键名
if (permission)
g_hash_table_insert(item, "permission", g_strdup(permission)); // 读写权限
if (description)
g_hash_table_insert(item, "description", g_strdup(description)); // 详细描述
if (summary)
g_hash_table_insert(item, "summary", g_strdup(summary)); // 概要
if (value_type)
g_hash_table_insert(item, "value_type", g_strdup(value_type)); // 类型
if (custom_value)
g_hash_table_insert(item, "custom_value", g_strdup(custom_value)); // 键值
if (default_value)
g_hash_table_insert(item, "default_value", g_strdup(default_value)); // 默认值
if (value_range)
g_hash_table_insert(item, "range", g_strdup(value_range)); // 取值范围
g_hash_table_insert(schema->values, g_strdup(node_name), item);
}
if (version)
{
for (int j = 0; versions[j]; j++)
{
for (int k = 0; k < 4; k++)
free(versions[j][k]);
free(versions[j]);
}
free(versions);
}
i++;
}
#undef APP_COLUMN
#undef VER_COLUMN
out:
if (rc != SQLITE_OK)
{
sqlite3_exec(db, "ROLLBACK", 0, 0, &err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
g_hash_table_destroy(schemas_table);
schemas_table = NULL;
}
if (apps)
{
for (int j = 0; apps[j]; j++)
{
for (int k = 0; k < 3; k++)
free(apps[j][k]);
{
if (apps[j][k])
free(apps[j][k]);
}
free(apps[j]);
}
free(apps);
}
out:
if (rc != SQLITE_OK && NULL != schemas_table)
if (versions)
{
g_hash_table_destroy(schemas_table);
schemas_table = NULL;
for (int j = 0; versions[j]; j++)
{
for (int k = 0; k < 4; k++)
{
if (versions[j][k])
free(versions[j][k]);
}
free(versions[j]);
}
free(versions);
}
if (configures)
{
for (int j = 0; configures[j]; j++)
{
for (int k = 0; k < 13; k++)
{
if (configures[j][k])
free(configures[j][k]);
}
free(configures[j]);
}
free(configures);
}
if (err_msg)
sqlite3_free(err_msg);
if (db)
sqlite3_close(db);
}
/*读取数据库*/
// 在schemas_table查找指定schema的配置句柄KSettingsSchema
KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *version)
@ -614,6 +771,7 @@ KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *versi
g_hash_table_iter_init(&iter, schemas_table);
while (g_hash_table_iter_next(&iter, &app_data, &version_hash))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> find %s\n", __func__, app_data->name);
if (0 == strcmp(app_data->name, list[0]))
{
VersionData *version_data = NULL;
@ -624,8 +782,16 @@ KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *versi
g_hash_table_iter_init(&iter_version, version_hash);
while (g_hash_table_iter_next(&iter_version, &version_data, &schemas))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> find %s '%s configure\n", __func__, app_data->name, version_data->name);
if (0 == strcmp(version_data->name, version))
{
GHashTableIter iter_schema;
g_hash_table_iter_init(&iter_schema, schemas);
char *few = NULL;
while (g_hash_table_iter_next(&iter_schema, &few, &result))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s with %s version 's id %s\n", __func__, app_data->name, version_data->name, few);
}
result = g_hash_table_lookup(schemas, id);
break;
}
@ -748,12 +914,12 @@ int kdk_conf2_schema_find_child(KSettingsSchema *schema, const char *name)
char *kdk_conf2_schema_key_value_type(GHashTable *key)
{
GET_KEY_ATTR(data_type)
GET_KEY_ATTR(value_type)
}
char *kdk_conf2_schema_key_get_value(GHashTable *key)
{
GET_KEY_ATTR(user_value)
GET_KEY_ATTR(custom_value)
}
char *kdk_conf2_schema_key_get_default_value(GHashTable *key)
@ -807,8 +973,8 @@ int kdk_conf2_schema_key_range_check(GHashTable *key, const char *value)
// if (NULL == tmp)
// {
if (0 == g_strcmp0(value, nick))
result = TRUE;
if (0 == g_strcmp0(value, nick))
result = TRUE;
// }
// else
// {
@ -868,7 +1034,7 @@ out:
char *kdk_conf2_schema_key_get_name(GHashTable *key)
{
GET_KEY_ATTR(property)
GET_KEY_ATTR(node_name)
}
char *kdk_conf2_schema_key_get_summary(GHashTable *key)
@ -920,9 +1086,14 @@ KSettingsSchema *kdk_conf2_schema_reload(const char *id, const char *version)
{
if (0 == strcmp(version_data->name, version))
{
result = g_hash_table_lookup(schemas, id);
// 用新读取的配置替换掉schemas_table中的老配置
KSettingsSchema *schema = _get_schema(id, version);
result = g_hash_table_lookup(schemas, id);
if (NULL == schema)
{
syslog(LOG_ERR, "[kysdk-conf2] %s -> :Update schema data failed\n", __func__);
break;
}
GHashTable *tmp = result->values;
result->values = schema->values;

View File

@ -22,6 +22,7 @@
#define KSETTINGSSCHEMA_H
#include <gio/gio.h>
#include <syslog.h>
#if __cplusplus
extern "C"
@ -45,6 +46,10 @@ extern "C"
GArray *children;
char *id;
char *version;
char *permission;
char *description;
char *summary;
char *extends;
} SchemaData;
typedef struct _SchemaData KSettingsSchema;

View File

@ -26,11 +26,13 @@
#include <gio/gio.h>
#include <pthread.h>
#include <stdarg.h>
#include <syslog.h>
#include <sys/stat.h>
#include <pwd.h>
#include <gio/gsettings.h>
#include "libkysettings.h"
#include "ksettingsschema.h"
#include "libkylog.h"
static GMainLoop *dbus_signal_loop = NULL; // glib主循环用于处理dbus消息事件主循环不开启无法接收dbus信号
static guint ref_count = 0; // 记录dbus_signal_loop的引用计数
@ -44,6 +46,7 @@ typedef struct _KSettingsPrivate
GMainContext *main_context;
KSettingsSchema *schema;
GDBusConnection *conn;
GSettings *gsettings;
guint sub_id[2];
} KSettingsPrivate;
@ -104,6 +107,11 @@ static void k_settings_finalize(GObject *object)
g_dbus_connection_signal_unsubscribe(ksettings->priv->conn, ksettings->priv->sub_id[SIGNAL_CHANGED]);
g_dbus_connection_signal_unsubscribe(ksettings->priv->conn, ksettings->priv->sub_id[SIGNAL_RELOAD]);
g_object_unref(ksettings->priv->conn);
if (ksettings->priv->gsettings)
{
g_settings_sync();
g_object_unref(ksettings->priv->gsettings);
}
}
G_OBJECT_CLASS(k_settings_parent_class)->finalize(object);
@ -144,11 +152,6 @@ static void k_settings_class_init(KSettingsClass *class)
0);
}
static int verify_file(char *file_name)
{
return 1;
}
/**
* @brief _g_main_loop_thread main_loop获取消息循环
* @param data
@ -161,6 +164,20 @@ static void *_g_main_loop_thread(void *data)
return NULL;
}
static void _on_gsettings_key_changed(GSettings *setting, const char *key, void *user_data)
{
GVariant *value = g_settings_get_value(setting, key);
KSettings *ksetting = (KSettings *)user_data;
char *conf2_value = kdk_conf2_get_value(ksetting, key);
if (0 == strcmp(conf2_value, g_variant_print(value, TRUE)))
return;
if (kdk_conf2_set_value(ksetting, key, g_variant_print(value, TRUE)))
{
// g_signal_emit(ksetting, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
}
g_variant_unref(value);
}
/**
* @brief _on_key_changed DBus服务中key_changed信号响应函数
* @param connection
@ -180,15 +197,41 @@ static void _on_key_changed(GDBusConnection *connection,
gpointer user_data)
{
KSettings *ksettings = (KSettings *)user_data;
char *id, *version, *key, *user;
g_variant_get(parameters, "(ssss)", &id, &version, &key, &user);
char *id, *version, *key;
g_variant_get(parameters, "(sss)", &id, &version, &key);
char *schema_id = kdk_conf2_schema_get_id(ksettings->priv->schema);
if ((0 == strcmp(schema_id, id)) && (0 == strcmp(g_get_user_name(), user)))
char *schema_version = kdk_conf2_schema_get_version(ksettings->priv->schema);
if ((0 == strcmp(schema_id, id)) && (0 == strcmp(schema_version, version)))
{
ksettings->priv->schema = kdk_conf2_schema_reload(id, version);
g_signal_emit(ksettings, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
syslog(LOG_INFO, "[kysdk-conf2] %s changed signal\n", key);
if (ksettings->priv->gsettings)
{
char *endptr = NULL;
GError *error = NULL;
GVariant *gsetting_value = g_settings_get_value(ksettings->priv->gsettings, key);
if (NULL != gsetting_value)
{
char *value = kdk_conf2_get_value(ksettings, key);
if (0 != strcmp(value, g_variant_print(gsetting_value, TRUE)))
{
char *type = kdk_conf2_get_type(ksettings, key);
GVariant *variant = g_variant_parse(type, value, NULL, &endptr, &error);
if (NULL == variant)
{
klog_err("[kysdk-conf2] %s -> %s\n", __func__, error->message);
return FALSE;
}
g_settings_set_value(ksettings->priv->gsettings, key, variant);
g_variant_unref(variant);
}
g_variant_unref(gsetting_value);
}
}
}
g_free(schema_id);
g_free(schema_version);
mutex = 0;
}
@ -243,7 +286,7 @@ static int _type_check(KSettings *ksettings, const char *key, const char *value)
GVariant *variant = g_variant_parse(G_VARIANT_TYPE(type), value, NULL, &endptr, &error);
if (NULL == variant)
{
printf("parser error : %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] % -> parser error : %s\n", __func__, error->message);
g_error_free(error);
g_free(type);
return FALSE;
@ -264,25 +307,21 @@ static int _type_check(KSettings *ksettings, const char *key, const char *value)
* @param value NULLmethod传参
* @return boolean类型 1 0
*/
static int _call_method(GDBusConnection *connection, const char *method, const char *id, const char *version, const char *key, const char *value)
static int _call_method(const char *method, const char *id, const char *version, const char *key, const char *value)
{
GError *error = NULL;
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (error != NULL)
{
syslog(LOG_ERR, "[kysdk-conf2] %s -> Connection Error: %s\n", __func__, error->message);
g_error_free(error);
return FALSE;
}
GDBusProxy *proxy;
GVariant *result;
int response = FALSE;
// 获取 DBus 会话总线
if (NULL == connection)
{
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (error != NULL)
{
g_printerr("Connection Error: %s\n", error->message);
g_error_free(error);
return response;
}
}
// 创建代理对象
proxy = g_dbus_proxy_new_sync(connection,
G_DBUS_PROXY_FLAGS_NONE,
@ -294,19 +333,33 @@ static int _call_method(GDBusConnection *connection, const char *method, const c
&error);
if (error != NULL)
{
g_printerr("Proxy Error: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> Proxy Error: %s\n", __func__, error->message);
g_error_free(error);
return response;
}
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Get user name failed! use root config\n", __func__);
strcpy(user_name, "root");
}
else
{
strcpy(user_name, pw->pw_name);
endpwent();
}
// 调用代理对象的方法
GVariant *variant = NULL;
if (0 == strcmp(method, "set"))
variant = g_variant_new("(sssss)", getlogin(), id, version, key, value);
variant = g_variant_new("(sssss)", user_name, id, version, key, value);
if (0 == strcmp(method, "reset"))
variant = g_variant_new("(ssss)", getlogin(), id, version, key);
variant = g_variant_new("(ssss)", user_name, id, version, key);
if (0 == strcmp(method, "reset_recursively"))
variant = g_variant_new("(sss)", getlogin(), id, version);
variant = g_variant_new("(sss)", user_name, id, version);
result = g_dbus_proxy_call_sync(proxy,
method,
@ -317,7 +370,7 @@ static int _call_method(GDBusConnection *connection, const char *method, const c
&error);
if (error != NULL)
{
g_printerr("Method Call Error: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> %s call fialed: %s\n", __func__, method, error->message);
g_error_free(error);
return response;
}
@ -328,6 +381,7 @@ static int _call_method(GDBusConnection *connection, const char *method, const c
// 释放资源
g_variant_unref(result);
g_object_unref(proxy);
g_object_unref(connection);
return response;
}
@ -335,9 +389,7 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
{
if (NULL == id)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "id is nullptr");
closelog();
syslog(LOG_INFO, "[kysdk-conf2] id is nullptr\n");
return NULL;
}
@ -346,40 +398,66 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
if (NULL == schemas_table)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "load user.db failed");
closelog();
syslog(LOG_INFO, "[kysdk-conf2] load user.db failed\n");
return NULL;
}
KSettingsSchema *schema = kdk_conf2_schema_table_lookup(id, version);
if (NULL == schema)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "invalied schema id");
closelog();
syslog(LOG_INFO, "[kysdk-conf2] invalied schema id\n");
return NULL;
}
KSettings *ksettings = g_object_new(K_TYPE_SETTINGS, NULL);
if (!K_IS_SETTINGS(ksettings))
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "init KSettings failed");
closelog();
syslog(LOG_INFO, "[kysdk-conf2] init KSettings failed\n");
return NULL;
}
char **gsettings_schemas = g_settings_list_schemas();
if (gsettings_schemas)
{
for (int i = 0; gsettings_schemas[i]; i++)
{
char *p = strstr(gsettings_schemas[i], id);
if (NULL == p)
continue;
int len = strlen(id);
if (*(p + len) == '\0')
{
ksettings->priv->gsettings = g_settings_new(gsettings_schemas[i]);
g_signal_connect(ksettings->priv->gsettings, "changed", G_CALLBACK(_on_gsettings_key_changed), ksettings);
}
}
}
ksettings->priv->schema = schema;
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
strcpy(user_name, "root");
}
else
{
strcpy(user_name, pw->pw_name);
endpwent();
}
// 创建dbus服务的链接用于调用接口及接收信号
GError *error = NULL;
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (0 == strcmp(user_name, "root"))
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
else
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
if (error != NULL)
{
openlog("kysdk-conf2", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Connection Error: %s\n", error->message);
closelog();
syslog(LOG_INFO, "[kysdk-conf2] Connection Error: %s\n", error->message);
g_object_unref(ksettings);
ksettings = NULL;
g_error_free(error);
@ -425,7 +503,6 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
void kdk_conf2_ksettings_destroy(KSettings *ksettings)
{
// g_assert(K_IS_SETTINGS(ksettings));
if (!K_IS_SETTINGS(ksettings))
return;
@ -443,7 +520,6 @@ void kdk_conf2_ksettings_destroy(KSettings *ksettings)
char *kdk_conf2_get_id(KSettings *ksettings)
{
// g_assert(K_IS_SETTINGS(ksettings));
if (!K_IS_SETTINGS(ksettings))
return NULL;
return kdk_conf2_schema_get_id(ksettings->priv->schema);
@ -451,7 +527,6 @@ char *kdk_conf2_get_id(KSettings *ksettings)
char *kdk_conf2_get_version(KSettings *ksettings)
{
// g_assert(K_IS_SETTINGS(ksettings));
if (!K_IS_SETTINGS(ksettings))
return NULL;
return strdup(kdk_conf2_schema_get_version(ksettings->priv->schema));
@ -459,9 +534,6 @@ char *kdk_conf2_get_version(KSettings *ksettings)
KSettings *kdk_conf2_get_child(KSettings *ksettings, const char *name)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != name);
if (!K_IS_SETTINGS(ksettings) || NULL == name)
return NULL;
@ -477,7 +549,6 @@ KSettings *kdk_conf2_get_child(KSettings *ksettings, const char *name)
char **kdk_conf2_list_children(KSettings *ksettings)
{
// g_assert(K_IS_SETTINGS(ksettings));
if (!K_IS_SETTINGS(ksettings))
return NULL;
@ -486,7 +557,6 @@ char **kdk_conf2_list_children(KSettings *ksettings)
char **kdk_conf2_list_keys(KSettings *ksettings)
{
// g_assert(K_IS_SETTINGS(ksettings));
if (!K_IS_SETTINGS(ksettings))
return NULL;
@ -495,8 +565,6 @@ char **kdk_conf2_list_keys(KSettings *ksettings)
char *kdk_conf2_get_range(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return NULL;
@ -506,8 +574,6 @@ char *kdk_conf2_get_range(KSettings *ksettings, const char *key)
int kdk_conf2_range_check(KSettings *ksettings, const char *key, const char *value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return FALSE;
@ -519,20 +585,27 @@ int kdk_conf2_range_check(KSettings *ksettings, const char *key, const char *val
int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
syslog(LOG_INFO, "[kysdk-conf2] %s -> Set the key '%s' of %s to %s\n", __func__, key, ksettings->priv->schema->id, value);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> assert ksettings is KSettings failed\n", __func__);
return FALSE;
}
if(0 == kdk_conf2_is_writable(ksettings, key))
if (0 == kdk_conf2_is_writable(ksettings, key))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s is unwritable\n", __func__, key);
return FALSE;
}
if (!_type_check(ksettings, key, value))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s type invalid\n", __func__, key);
return FALSE;
}
if (!kdk_conf2_range_check(ksettings, key, value))
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s vlaue is not in range\n", __func__, key);
return FALSE;
}
@ -546,7 +619,7 @@ int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value
char *id = kdk_conf2_schema_get_id(ksettings->priv->schema);
char *version = kdk_conf2_schema_get_version(ksettings->priv->schema);
if (NULL == curr_value || 0 != strcmp(curr_value, value))
result = _call_method(ksettings->priv->conn, "set",
result = _call_method("set",
id,
version,
key, value);
@ -555,13 +628,15 @@ int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value
g_free(id);
g_free(version);
g_free(curr_value);
syslog(LOG_INFO, "[kysdk-conf2] %s -> Set value finished. Return %s\n", __func__, result ? "true" : "false");
return result;
}
char *kdk_conf2_get_value(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
syslog(LOG_INFO, "[kysdk-conf2] %s -> Get value start\n", __func__);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return NULL;
@ -574,13 +649,12 @@ char *kdk_conf2_get_value(KSettings *ksettings, const char *key)
{
value = kdk_conf2_schema_key_get_default_value(key_hash);
}
syslog(LOG_INFO, "[kysdk-conf2] %s -> Get value end\n", __func__);
return value;
}
char *kdk_conf2_get_default_value(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return NULL;
@ -590,8 +664,6 @@ char *kdk_conf2_get_default_value(KSettings *ksettings, const char *key)
int kdk_conf2_set_boolean(KSettings *ksettings, const char *key, int value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return FALSE;
@ -632,8 +704,6 @@ int kdk_conf2_get_default_boolean(KSettings *ksettings, const char *key)
int kdk_conf2_set_double(KSettings *ksettings, const char *key, double value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -669,8 +739,6 @@ double kdk_conf2_get_default_double(KSettings *ksettings, const char *key)
int kdk_conf2_set_enum(KSettings *ksettings, const char *key, int value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -684,7 +752,7 @@ int kdk_conf2_set_enum(KSettings *ksettings, const char *key, int value)
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
if (variant == NULL)
{
g_print("解析失败: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
g_error_free(error);
goto out;
}
@ -700,7 +768,7 @@ int kdk_conf2_set_enum(KSettings *ksettings, const char *key, int value)
{
char set_value[1024];
sprintf(set_value, "%d", value);
result = kdk_conf2_set_value(ksettings, key, set_value);
result = kdk_conf2_set_value(ksettings, key, nick);
break;
}
}
@ -726,7 +794,7 @@ int kdk_conf2_get_enum(KSettings *ksettings, const char *key)
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
if (variant == NULL)
{
g_print("解析失败: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
g_error_free(error);
goto out;
}
@ -767,7 +835,7 @@ int kdk_conf2_get_default_enum(KSettings *ksettings, const char *key)
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
if (variant == NULL)
{
g_print("解析失败: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
g_error_free(error);
goto out;
}
@ -795,8 +863,6 @@ out:
int kdk_conf2_set_int(KSettings *ksettings, const char *key, int value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -833,8 +899,6 @@ int kdk_conf2_get_default_int(KSettings *ksettings, const char *key)
int kdk_conf2_set_int64(KSettings *ksettings, const char *key, long value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -857,8 +921,7 @@ long kdk_conf2_get_int64(KSettings *ksettings, const char *key)
return result;
}
long kdk_conf2_get_default_int64(KSettings *ksettings,
const char *key)
long kdk_conf2_get_default_int64(KSettings *ksettings, const char *key)
{
long result = 0;
char *value = kdk_conf2_get_default_value(ksettings, key);
@ -872,8 +935,6 @@ long kdk_conf2_get_default_int64(KSettings *ksettings,
int kdk_conf2_set_uint(KSettings *ksettings, const char *key, unsigned int value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -910,8 +971,6 @@ unsigned int kdk_conf2_get_default_uint(KSettings *ksettings, const char *key)
int kdk_conf2_set_uint64(KSettings *ksettings, const char *key, unsigned long value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -948,14 +1007,10 @@ unsigned long kdk_conf2_get_default_uint64(KSettings *ksettings, const char *key
int kdk_conf2_set_string(KSettings *ksettings, const char *key, const char *value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
GVariant *variant = g_variant_new_string(value);
int result = kdk_conf2_set_value(ksettings, key, g_variant_print(variant, FALSE));
g_variant_unref(variant);
int result = kdk_conf2_set_value(ksettings, key, value);
return result;
}
@ -972,8 +1027,6 @@ char *kdk_conf2_get_default_string(KSettings *ksettings, const char *key)
int kdk_conf2_set_strv(KSettings *ksettings, const char *key, const char *const *value)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return 0;
@ -1001,7 +1054,7 @@ char **kdk_conf2_get_strv(KSettings *ksettings, const char *key)
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("as"), value, NULL, &endptr, &error);
if (NULL == variant)
{
g_print("解析失败: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
g_free(value);
g_error_free(error);
return NULL;
@ -1026,7 +1079,7 @@ char **kdk_conf2_get_default_strv(KSettings *ksettings, const char *key)
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("as"), value, NULL, &endptr, &error);
if (NULL == variant)
{
g_print("解析失败: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
g_free(value);
g_error_free(error);
return NULL;
@ -1040,8 +1093,6 @@ char **kdk_conf2_get_default_strv(KSettings *ksettings, const char *key)
char *kdk_conf2_get_descrition(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return NULL;
@ -1051,8 +1102,6 @@ char *kdk_conf2_get_descrition(KSettings *ksettings, const char *key)
char *kdk_conf2_get_summary(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return NULL;
@ -1062,8 +1111,6 @@ char *kdk_conf2_get_summary(KSettings *ksettings, const char *key)
char *kdk_conf2_get_type(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return NULL;
@ -1073,14 +1120,16 @@ char *kdk_conf2_get_type(KSettings *ksettings, const char *key)
void kdk_conf2_reset(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return;
if (NULL == kdk_conf2_schema_get_key(ksettings->priv->schema, key))
return;
syslog(LOG_INFO, "[kysdk-conf2] %s -> :reset %s value\n", __func__, key);
char *id = kdk_conf2_schema_get_id(ksettings->priv->schema);
char *version = kdk_conf2_schema_get_version(ksettings->priv->schema);
_call_method(ksettings->priv->conn, "reset",
_call_method("reset",
id,
version,
key, NULL);
@ -1090,8 +1139,6 @@ void kdk_conf2_reset(KSettings *ksettings, const char *key)
int kdk_conf2_is_writable(KSettings *ksettings, const char *key)
{
// g_assert(K_IS_SETTINGS(ksettings));
// g_assert(NULL != key);
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return FALSE;
@ -1106,9 +1153,9 @@ int kdk_conf2_has_key(KSettings *ksettings, const char *key)
{
if (!K_IS_SETTINGS(ksettings) || NULL == key)
return FALSE;
GHashTable *key_hash = kdk_conf2_schema_get_key(ksettings->priv->schema, key);
if(NULL == key_hash)
if (NULL == key_hash)
return 0;
else
return 1;
@ -1116,7 +1163,6 @@ int kdk_conf2_has_key(KSettings *ksettings, const char *key)
unsigned long kdk_conf2_connect_signal(KSettings *ksettings, const char *signal_name, KCallBack handler, void *user_data)
{
// g_assert(K_IS_SETTINGS(ksettings));
if (!K_IS_SETTINGS(ksettings))
return 0;
@ -1125,15 +1171,7 @@ unsigned long kdk_conf2_connect_signal(KSettings *ksettings, const char *signal_
void kdk_conf2_reload()
{
GError *error = NULL;
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (error != NULL)
{
g_printerr("Connection Error: %s\n", error->message);
g_error_free(error);
return;
}
_call_method(connection, "reload", NULL, NULL, NULL, NULL);
_call_method("reload", NULL, NULL, NULL, NULL);
}
char **kdk_conf2_list_schemas(const char *app, const char *version)
@ -1183,12 +1221,13 @@ char **kdk_conf2_list_schemas(const char *app, const char *version)
int kdk_conf2_save_user_configure(const char *path)
{
if(0 != access(path, F_OK))
syslog(LOG_INFO, "[kysdk-conf2] %s -> save user config start\n", __func__);
char real_path[4096];
memset(real_path, 0, sizeof(real_path));
if (!realpath(path, real_path))
{
if(!verify_file(path))
return FALSE;
if (mkdir(path, 0777) < 0)
return FALSE;
syslog(LOG_INFO, "[kysdk-conf2] %s -> path not exists\n", __func__);
return FALSE;
}
GDBusConnection *connection;
@ -1204,7 +1243,7 @@ int kdk_conf2_save_user_configure(const char *path)
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (error != NULL)
{
g_printerr("Connection Error: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> Connection Error: %s\n", __func__, error->message);
g_error_free(error);
return response;
}
@ -1221,11 +1260,26 @@ int kdk_conf2_save_user_configure(const char *path)
&error);
if (error != NULL)
{
g_printerr("Proxy Error: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> Proxy Error: %s\n", error->message);
g_error_free(error);
return response;
}
GVariant *variant = g_variant_new("(ss)", getlogin(), path);
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
syslog(LOG_INFO, "【kysdk-conf2】 Get user name failed! use root config\n");
strcpy(user_name, "root");
}
else
{
strcpy(user_name, pw->pw_name);
endpwent();
}
GVariant *variant = g_variant_new("(ss)", user_name, real_path);
result = g_dbus_proxy_call_sync(proxy,
"save",
variant,
@ -1235,7 +1289,7 @@ int kdk_conf2_save_user_configure(const char *path)
&error);
if (error != NULL)
{
g_printerr("Method Call Error: %s\n", error->message);
syslog(LOG_ERR, "[kysdk-conf2] %s -> Method Call Error: %s\n", __func__, error->message);
g_error_free(error);
return response;
}
@ -1246,5 +1300,132 @@ int kdk_conf2_save_user_configure(const char *path)
// 释放资源
g_variant_unref(result);
g_object_unref(proxy);
syslog(LOG_INFO, "[kysdk-conf2] %s -> save user config end\n", __func__);
return response;
}
KSettings *kdk_conf2_new_extends_id(const char *old_id, const char *new_id, const char *version)
{
KSettings *setting = kdk_conf2_new(new_id, version);
if (NULL != setting)
return setting;
syslog(LOG_INFO, "[kysdk-conf2] %s -> creat new id : %s\n", __func__, new_id);
GDBusConnection *connection;
GError *error = NULL;
GDBusProxy *proxy;
GVariant *result;
int response = FALSE;
// 获取 DBus 会话总线
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (NULL == connection)
{
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
if (error != NULL)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Connection Error: %s\n", __func__, error->message);
g_error_free(error);
return NULL;
}
}
// 创建代理对象
proxy = g_dbus_proxy_new_sync(connection,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"com.kylin.kysdk.conf2",
"/com/kylin/kysdk/conf2",
"com.kylin.kysdk.conf2",
NULL,
&error);
if (error != NULL)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Proxy Error: %s\n", __func__, error->message);
g_error_free(error);
return NULL;
}
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
syslog(LOG_INFO, "【kysdk-conf2】 Get user name failed! use root config\n");
strcpy(user_name, "root");
}
else
{
strcpy(user_name, pw->pw_name);
endpwent();
}
GVariant *variant = g_variant_new("(ssss)",
old_id,
new_id,
version ? version : "",
user_name);
result = g_dbus_proxy_call_sync(proxy,
"extends_id",
variant,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (error != NULL)
{
syslog(LOG_INFO, "[kysdk-conf2] %s -> Method Call Error: %s\n", __func__, error->message);
g_error_free(error);
return NULL;
}
// 处理方法调用的返回值
g_variant_get(result, "(b)", &response);
// 释放资源
g_variant_unref(result);
g_object_unref(proxy);
if (response)
{
kdk_conf2_schema_update_schemas_table();
return kdk_conf2_new(new_id, version);
}
return NULL;
}
int kdk_conf2_is_schema(const char *id, const char *version)
{
if (NULL == id)
{
syslog(LOG_INFO, "[kysdk-conf2] %s ->: id is NULL\n", __func__);
return FALSE;
}
if (NULL == schemas_table)
kdk_conf2_schema_update_schemas_table();
if (NULL == schemas_table)
{
syslog(LOG_INFO, "[kysdk-conf2] %s ->: load user.db failed\n", __func__);
return FALSE;
}
KSettingsSchema *schema = kdk_conf2_schema_table_lookup(id, version);
if (NULL == schema)
{
syslog(LOG_INFO, "[kysdk-conf2] %s ->: schema not existed\n", __func__);
return FALSE;
}
return TRUE;
}
char *kdk_conf2_get_schema_summary(KSettings *ksettings)
{
return ksettings->priv->schema->summary ? strdup(ksettings->priv->schema->summary) : NULL;
}
char *kdk_conf2_get_schema_desription(KSettings *ksettings)
{
return ksettings->priv->schema->description ? strdup(ksettings->priv->schema->description) : NULL;
}

View File

@ -178,6 +178,7 @@ extern "C"
const char *signal_name,
KCallBack handler,
void *user_data);
void kdk_conf2_reload (void);
char ** kdk_conf2_list_schemas (const char *app,
@ -185,21 +186,16 @@ extern "C"
int kdk_conf2_save_user_configure (const char *path);
KSettings * kdk_conf2_new_extends_id (const char *old_id,
const char *new_id,
const char *version);
int kdk_conf2_is_schema (const char *id,
const char *version);
char * kdk_conf2_get_schema_summary (KSettings *ksettings);
char * kdk_conf2_get_schema_desription (KSettings *ksettings);
#if __cplusplus
}
#endif // extern "C"

View File

@ -0,0 +1,13 @@
dirs:
- basic
- industry
- vendor
- production
- project
- kcm
#通用配置与应用下组名的映射关系
mapping:
#通用配置组名
powermanager:
#应用名:组名
control-center: powermanager

View File

@ -0,0 +1,8 @@
[whitelist]
key2 = /usr/bin/kconf2
key3 = /usr/bin/kconf2-editor
key4 = /usr/bin/ukui-settings-daemon
key5 = /usr/sbin/lightdm
key6 = /usr/bin/ukui-screensaver-dialog
key7 = /usr/sbin/ukui-greeter
key8 = /lib/systemd/systemd-logind

View File

@ -0,0 +1 @@
f45558b6a1cb69ceb6e4e58d8b9a47b551db8543

View File

@ -1,3 +1,4 @@
#!/usr/bin/python3.8
#
# libkysdk-system's Library
#
@ -16,414 +17,91 @@
# You should have received a copy of the GNU General Public License
# along with this library. If not, see <https://www.gnu.org/licenses/>.
#
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
#
#
#!/usr/bin/python3
import yaml, sqlite3
import os, re, shutil
import logging, traceback
import os
import logging
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
import conf2Utils
from configparser import ConfigParser
logger = None
programWhiteList = []
envBlackList = ('LD_PRELOAD', 'LD_LIBRARY_PATH', 'LD_AUDIT',)
# 创建一个DBus服务类
class KYSettingsDBusService(dbus.service.Object):
__read_only_view = {}
__root_view = {}
def __init__(self, bus_name, object_path):
logger.info(f'DBus Class init')
dbus.service.Object.__init__(self, bus_name, object_path)
os.makedirs('/etc/kylin-config', exist_ok=True)
#初始化日志模块
logging.basicConfig(filename='/etc/kylin-config/systembus.log', level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s \n %(message)s')
self.logger = logging.getLogger('/etc/kylin-config/systembus.log')
self._converter = conf2Utils.Converter(logger)
self._watchdog = conf2Utils.FileWatche('/etc/kylin-config/basic', self)
self.__creat_db_file__()
self._reload()
if os.path.exists('/etc/dbus-1/conf/com.kylin.kysdk.conf2.limit'):
conf = ConfigParser()
conf.read('/etc/dbus-1/conf/com.kylin.kysdk.conf2.limit')
# conf.read('/home/kylin/disk/kylinos-src/libkysdk-base/src/conf2/service/com.kylin.kysdk.conf2.limit')
if conf.has_section('whitelist'):
global programWhiteList
programWhiteList = list(conf['whitelist'].values())
#读配置文件创建只读视图数据库和root用户的数据库
def __creat_db_file__(self):
try:
#加载只读配置,写入数据库
self.__load_read_only_view__()
self.__dict2db__(self.__read_only_view, '/etc/kylin-config/user.db')
logger.info(f'DBus Class init end')
#copy文件到root用户目录
if os.path.exists('/etc/kylin-config/user.db'):
if not os.path.exists('/root/.config/kylin-config/user.db'):
os.makedirs(os.path.dirname('/root/.config/kylin-config/'), exist_ok=True)
shutil.copyfile('/etc/kylin-config/user.db', '/root/.config/kylin-config/user.db')
self.__root_view = self.__format_db_file('/root/.config/kylin-config/user.db')
else:
self.__root_view = self.__format_db_file('/root/.config/kylin-config/user.db')
self.__del_discarded_key(self.__root_view, self.__read_only_view)
self.__merge_dict(self.__root_view, self.__read_only_view)
self.__dict2db__(self.__root_view, '/root/.config/kylin-config/user.db')
except Exception as e:
self.logger.error(traceback.format_exc())
#统一视图写入数据库
#递归寻找枚举
def __recursive_search__(self, dictionary, key):
if key in dictionary:
return dictionary[key]
else:
for value in dictionary.values():
if isinstance(value, dict):
result = self.__recursive_search__(value, key)
if result is not None:
return result
return None
#递归写入配置数据到配置表
def __write_element_in_table__(self, version_data:dict ,data: dict, cursor: sqlite3.Cursor, version_id, parent_id):
#key写入到数据库
if 'keys' in data:
keys = data['keys']
for key in keys:
property = key
user_value = keys[key].get('value')
# if user_value is None:
# user_value = keys[key].get('default')
type = keys[key].get('_type')
default_value = keys[key].get('default')
if isinstance(default_value, str) is False:
default_value = str(default_value)
description = keys[key].get('description')
summary = keys[key].get('summary')
permission = keys[key].get('permission')
if permission is None:
permission = 'public'
#TODO: 计算range取值范围
range = keys[key].get('range')
# reload时没有更新的枚举数据的range应该是枚举参数的字符串列表
# 更新后或初始化时的枚举数据的range是@[枚举名]
if type == 'enum' and isinstance(range, str) and range.startswith('@'):
enum_range = {}
element_list = self.__recursive_search__(version_data,keys[key]['range'][1:])
for element in element_list:
enum_range[element['nick']] = int(element['value'])
range = str(enum_range)
cursor.execute('''INSERT INTO configures (version_id, property, user_value, data_type, default_value, permission, range, parent, description, summary)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',(version_id, property, user_value, type, default_value, permission, range, parent_id, description, summary))
if 'children' in data:
children = data['children']
for child in children:
if child.startswith('enum_'):
continue
cursor.execute("INSERT INTO configures (version_id,group_name,parent) VALUES (?, ?, ?)",(version_id,child,parent_id))
group_id = cursor.lastrowid
self.__write_element_in_table__(version_data,children[child],cursor,version_id,group_id)
#创建app表
def __covert_app_table__(self,data: dict, cursor: sqlite3.Cursor):
# 创建app表
cursor.execute('''CREATE TABLE IF NOT EXISTS app
(id INTEGER PRIMARY KEY AUTOINCREMENT,
app_name TEXT,
defualt_version TEXT)''')
#将app信息写入app表
for app in data.keys():
default_version = data[app].get('default_version')
# 如果没有设置默认版本,将默认版本设置为最大版本
if default_version is None:
for version in data[app]:
if default_version is None:
default_version = version
#比较版本 版本目前认为是2.0.0-0k0格式
default_list = re.findall(r'\d+', default_version)
list = re.findall(r'\d+', version)
for i in range(0,6):
if len(default_list) == i:
default_version = version
break
if len(list) == i:
break
if int(default_list[i]) < int(list[i]):
default_version = version
break
if int(default_list[i]) > int(list[i]):
break
cursor.execute("INSERT INTO app (app_name, defualt_version) VALUES (?,?)",(app, default_version))
#创建版本表
def __covert_version_table__(self,data: dict, cursor: sqlite3.Cursor):
# 创建version表
cursor.execute('''CREATE TABLE IF NOT EXISTS version
(id INTEGER PRIMARY KEY AUTOINCREMENT,
app_id INTEGER,
version TEXT,
compatible TEXT,
FOREIGN KEY (app_id) REFERENCES app(id))''')
for app in data.keys():
cursor.execute("SELECT id FROM app WHERE app_name = ?", (app,))
appId = cursor.fetchone()
for version in data[app].keys():
if(version == 'default_version'):
continue
cursor.execute("INSERT INTO version (app_id,version, compatible) VALUES (?, ?, ?)",(appId[0],version, data[app][version].get('compatible')))
#创建配置表
def __covert_configure_table__(self, data: dict, cursor: sqlite3.Cursor):
# 创建version表
cursor.execute('''CREATE TABLE IF NOT EXISTS configures
(id INTEGER PRIMARY KEY AUTOINCREMENT,
version_id INTEGER,
property TEXT,
group_name TEXT,
user_value TEXT,
data_type TEXT,
default_value TEXT,
permission TEXT,
range TEXT,
parent INTEGER,
description TEXT,
summary TEXT,
FOREIGN KEY (version_id) REFERENCES version(id),
FOREIGN KEY (parent) REFERENCES configures(id))''')
cursor.execute("SELECT * FROM app")
apps = cursor.fetchall()
for app in apps:
cursor.execute("SELECT * FROM version WHERE app_id = ?", (app[0],))
versions = cursor.fetchall()
for version in versions:
version_data = data[app[1]][version[2]]
#keys写入数据库
self.__write_element_in_table__(version_data,version_data,cursor,version[0],0)
#将字典中的配置数据写入数据库
def __dict2db__(self, dict, path):
try:
# 连接到数据库(如果不存在则创建)
db_file_path = path.rsplit('/',maxsplit=1)[0]
if not os.path.exists(db_file_path):
os.makedirs(db_file_path)
conn = sqlite3.connect(path)
# 创建游标对象
cursor = conn.cursor()
conn.execute('BEGIN TRANSACTION')
# 获取数据库中的所有表名
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = cursor.fetchall()
# 遍历所有表名对每个表执行DELETE语句以删除所有行
for table in tables:
cursor.execute(f"DELETE FROM {table[0]}")
# cursor.execute(f"DELETE FROM sqlite_sequence WHERE name={table[0]}")
self.__covert_app_table__(dict,cursor)
self.__covert_version_table__(dict,cursor)
self.__covert_configure_table__(dict,cursor)
# 提交更改
conn.commit()
conn.close()
return 0
except sqlite3.Error as e:
conn.rollback()
conn.close()
self.logger.error(traceback.format_exc())
return -1
#读取数据库数据到内存
#递归读取数据库数据到字典
def __format_element(self, parent: dict, cursor: sqlite3.Cursor, version_id, parent_id):
keys = {}
children = {}
cursor.execute('SELECT * FROM configures WHERE version_id = ? AND parent = ?', (version_id,parent_id))
configure_data = cursor.fetchall()
for configure in configure_data:
#读取子分组
if configure[3] is not None:
children[configure[3]] = {}
self.__format_element(children[configure[3]],cursor,version_id,configure[0])
#读取key
else:
keys[configure[2]] = {}
if configure[4] is not None:
keys[configure[2]]['value'] = configure[4]
if configure[5] is not None:
keys[configure[2]]['_type'] = configure[5]
if configure[6] is not None:
keys[configure[2]]['default'] = configure[6]
if configure[7] is not None:
keys[configure[2]]['permission'] = configure[7]
if configure[8] is not None:
keys[configure[2]]['range'] = configure[8]
if configure[10] is not None:
keys[configure[2]]['description'] = configure[10]
if configure[11] is not None:
keys[configure[2]]['summary'] = configure[11]
if keys:
parent['keys'] = keys
if children:
parent['children'] = children
#将数据库中的内容读取到数据结构中
def __format_db_file(self, db_file: str):
try:
data = {}
# 连接到数据库(如果不存在则创建)
conn = sqlite3.connect(db_file)
if conn is None:
return data
# 创建游标对象
cursor = conn.cursor()
conn.execute('BEGIN TRANSACTION')
#遍历app表
cursor.execute('SELECT * FROM app')
app_data = cursor.fetchall()
for app in app_data:
data[app[1]] = {}
cursor.execute('SELECT * FROM version WHERE app_id = ?', (app[0],))
version_data = cursor.fetchall()
for version in version_data:
data[app[1]][version[2]] = {}
self.__format_element(data[app[1]][version[2]],cursor,version[0],0)
conn.close()
return data
except Exception as e:
conn.rollback()
conn.close()
self.logger.error(traceback.format_exc())
return {}
#读取yaml配置文件到字典
def __load_config__(self, yaml_dir):
if not os.path.exists(yaml_dir):
return {}
yaml_data = {}
for root,dirs,files in os.walk(yaml_dir):
for file in files:
if file.endswith('.yaml'):
with open(f'{yaml_dir}/{file}','r') as tmp_file:
yaml_str = tmp_file.read()
tmp_data = yaml.safe_load(yaml_str)
yaml_data.update(tmp_data)
return yaml_data
#合并、覆盖两个字典
def __merge_dict(self, dest:dict , src:dict):
if src is None:
return dest
for key, value in src.items():
if key in dest and isinstance(dest[key], dict) and isinstance(src[key], dict):
self.__merge_dict(dest[key], src[key])
else:
dest[key] = value
return dest
def __del_discarded_key(self, dest:dict, src:dict):
keys_to_delete = []
for key in dest:
if not isinstance(dest[key], dict):
return
if key not in src:
keys_to_delete.append(key)
else:
self.__del_discarded_key(dest[key], src[key])
for key in keys_to_delete:
dest.pop(key)
#统一配置文件内容覆盖
def __common_override(self, dest:dict, src:dict):
if 'children' not in dest:
def isAllowedCaller(self,sender):
if sender is None:
return
for group in src:
if group in dest['children']:
for key in src[group]['keys']:
if key in dest['children'][group]['keys']:
dest['children'][group]['keys'][key].update(src[group]['keys'][key])
# self.__merge_dict(dest['children'][group], src[group])
for child in dest['children']:
if child != group:
self.__common_override(dest['children'][child], src)
pid = self.getSenderPid(sender)
self.checkSenderEnv(pid)
exe_file = '/proc/%u/exe' % pid
real_file = os.readlink(exe_file)
if real_file.startswith('/usr/bin/python'):
cmd_file = '/proc/%u/cmdline' % pid
with open(cmd_file, 'r') as cf:
cmd_line = cf.readline()
cmds = cmd_line.split('\0')
if len(cmds) >= 2:
real_file = cmds[1]
if real_file not in programWhiteList:
raise dbus.exceptions.DBusException('[%s] dbus method control,operation not permitted' % real_file)
# 加载只读配置,更新只读视图数据库文件
def __load_read_only_view__(self):
self.__read_only_view.clear()
# 只读文件目录
self.__read_only_view.update(self.__load_config__('/etc/kylin-config/basic'))
def getSenderPid(self,sender):
system_bus = dbus.SystemBus()
dbus_obj = system_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
inter_obj = dbus.Interface(dbus_obj, dbus_interface='org.freedesktop.DBus')
try:
pid = inter_obj.GetConnectionUnixProcessID(sender)
except dbus.DBusException as e:
raise dbus.exceptions.DBusException('[%s] dbus method control,operation not permitted' % sender)
return pid
data = self.__load_config__('/etc/kylin-config/production')
self.__merge_dict(self.__read_only_view, data)
def checkSenderEnv(self, pid):
env_file = '/proc/%u/environ' % pid
with open(env_file, 'r') as ef:
env_lines = ef.readline()
env_details = env_lines.replace('\0', '\n').split('\n')
for env_detail in env_details:
key = env_detail.split('=')[0]
if key in envBlackList:
raise dbus.exceptions.DBusException('[%u] dbus method control,env forbidden' % pid)
data = self.__load_config__('/etc/kylin-config/vendor')
self.__merge_dict(self.__read_only_view, data)
data = self.__load_config__('/etc/kylin-config/industry')
self.__merge_dict(self.__read_only_view, data)
data = self.__load_config__('/etc/kylin-config/project')
self.__merge_dict(self.__read_only_view, data)
data = self.__load_config__('/etc/kylin-config/control')
self.__merge_dict(self.__read_only_view, data)
data = self.__load_config__('/etc/kylin-config/common')
if data:
for app in self.__read_only_view:
for version in self.__read_only_view[app]:
self.__common_override(self.__read_only_view[app][version], data)
#将字典中的配置数据写入数据库
def __dict2db__(self, dict, path):
try:
# 连接到数据库(如果不存在则创建)
db_file_path = path.rsplit('/',maxsplit=1)[0]
if not os.path.exists(db_file_path):
os.makedirs(db_file_path)
conn = sqlite3.connect(path)
# 创建游标对象
cursor = conn.cursor()
conn.execute('BEGIN TRANSACTION')
# 获取数据库中的所有表名
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = cursor.fetchall()
# 遍历所有表名对每个表执行DELETE语句以删除所有行
for table in tables:
cursor.execute(f"DELETE FROM {table[0]}")
# cursor.execute(f"DELETE FROM sqlite_sequence WHERE name={table[0]}")
self.__covert_app_table__(dict,cursor)
self.__covert_version_table__(dict,cursor)
self.__covert_configure_table__(dict,cursor)
# 提交更改
conn.commit()
conn.close()
return 0
except Exception as e:
conn.rollback()
conn.close()
self.logger.error(traceback.format_exc())
return -1
# 重载
def _reload(self):
if self._converter.update_read_only_db():
if self._converter.update_user_db('/root/.config/kylin-config/user.db'):
return True
return False
# key值改变信号
@dbus.service.signal("com.kylin.kysdk.conf2", signature='ssss')
def key_changed(self, id, version, key, user):
@dbus.service.signal("com.kylin.kysdk.conf2", signature='sss')
def key_changed(self, id, version, key):
pass
# 配置信息update信号
@ -432,187 +110,72 @@ class KYSettingsDBusService(dbus.service.Object):
pass
# 设置一个配置的值
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='sssss', out_signature='i')
def set(self, user, id, version, key, value):
try:
# 修改用户配置文件,写入到数据库
group_list = id.split('.')
sql_path = ''
if user == 'root':
sql_path = '/root/.config/kylin-config/user.db'
else:
sql_path = f'/home/{user}/.config/kylin-config/user.db'
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='sssss', out_signature='i', sender_keyword='sender')
def set(self, user, id, version, key, value, sender = None):
# self.isAllowedCaller(sender)
success = False
if user == 'root':
success = self._converter.set('/root/.config/kylin-config/user.db', id, version, key, value)
else:
success = self._converter.set(f'/home/{user}/.config/kylin-config/user.db', id, version, key, value)
conn = sqlite3.connect(sql_path)
# 创建游标对象
cursor = conn.cursor()
if success:
self.key_changed(id, version, key)
# 开始写入事务
conn.execute('BEGIN TRANSACTION')
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
app_id = cursor.fetchone()[0]
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id, version))
version_id = cursor.fetchone()[0]
parent_id = 0
# 查找组
for group_name in group_list[1:]:
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND group_name = ?", (version_id, parent_id, group_name))
parent_id = cursor.fetchone()[0]
# cursor.execute("SELECT * FROM configures WHERE version_id = ? AND parent = ? AND property = ?", (version_id, parent_id, key))
# key_data = cursor.fetchone()
cursor.execute("UPDATE configures SET user_value = ? WHERE version_id = ? AND parent = ? AND property = ?", (value,version_id, parent_id, key))
conn.commit()
conn.close()
if user == 'root':
self.__merge_dict(self.__root_view, self.__format_db_file('/root/.config/kylin-config/user.db'))
self.key_changed(id, version, key, user)
return 1
except Exception as e:
conn.rollback()
conn.close()
self.logger.error(traceback.format_exc())
return 0
return success
# 恢复单个默认值
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='i')
def reset(self,user, id, version, key):
try:
# 修改用户配置文件,写入到数据库
group_list = id.split('.')
sql_path = ''
if user == 'root':
sql_path = '/root/.config/kylin-config/user.db'
else:
sql_path = f'/home/{user}/.config/kylin-config/user.db'
conn = sqlite3.connect(sql_path)
# 创建游标对象
cursor = conn.cursor()
# 开始写入事务
conn.execute('BEGIN TRANSACTION')
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
app_id = cursor.fetchone()[0]
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id,version))
version_id = cursor.fetchone()[0]
parent_id = 0
# 查找组
for group_name in group_list[1:]:
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND group_name = ?", (version_id, parent_id, group_name))
parent_id = cursor.fetchone()[0]
# cursor.execute("SELECT * FROM configures WHERE version_id = ? AND parent = ? AND property = ?", (version_id, parent_id, key))
cursor.execute("UPDATE configures SET user_value = default_value WHERE version_id = ? AND parent = ? AND property = ?", (version_id, parent_id, key))
conn.commit()
conn.close()
if user == 'root':
self.__merge_dict(self.__root_view, self.__format_db_file('/root/.config/kylin-config/user.db'))
self.key_changed(id,version,key, user)
return 0
except Exception as e:
conn.rollback()
conn.close()
self.logger.error(traceback.format_exc())
return -1
# 恢复整个id的默认值
# @dbus.service.method("com.kylin.kysdk.conf2", in_signature='sss', out_signature='i')
# def reset_recursively(self, user, id, version):
# try:
# # 修改用户配置文件,写入到数据库
# group_list = id.split('.')
# if user == 'root':
# sql_path = '/root/.config/kylin-config/user.db'
# else:
# sql_path = f'/home/{user}/.config/kylin-config/user.db'
# conn = sqlite3.connect(sql_path)
# # 创建游标对象
# cursor = conn.cursor()
# # 开始写入事务
# conn.execute('BEGIN TRANSACTION')
# cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
# app_id = cursor.fetchone()[0]
# cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id,version))
# version_id = cursor.fetchone()[0]
# parent_id = 0
# # 查找组
# for group_name in group_list[1:]:
# cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND group_name = ?", (version_id, parent_id, group_name))
# parent_id = cursor.fetchone()[0]
# cursor.execute("UPDATE configures SET value = default_value WHERE version_id = ? AND parent = ?", (version_id, parent_id))
# conn.commit()
# conn.close()
# if user == 'root':
# self.__merge_dict(self.__root_view, self.__format_db_file('/root/.config/kylin-config/user.db'))
# self.key_changed(id,version,None)
# return 0
# except sqlite3.Error as e:
# conn.rollback()
# conn.close()
# return -1
# 恢复整个id的默认值
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='', out_signature='i')
def reload(self):
try:
self.__load_read_only_view__()
self.__dict2db__(self.__read_only_view, '/etc/kylin-config/user.db')
#删除配置文件中删除的键
self.__del_discarded_key(self.__root_view, self.__read_only_view)
#合并配置新增和修改
self.__merge_dict(self.__root_view, self.__read_only_view)
self.__dict2db__(self.__root_view, '/root/.config/kylin-config/user.db')
self.updated()
return 1
except Exception as e:
self.logger.error(traceback.format_exc())
return 0
def __value_override_default(self, dest:dict, src:dict):
for key, value in src.items():
if key not in dest:
continue
if isinstance(src[key], dict):
self.__value_override_default(dest[key], src[key])
else:
if src['value'] is not None:
dest['default'] = src['value']
return
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ss', out_signature='b')
def save(self, user, path):
if not os.path.exists(path):
return False
data = {}
if 'root' == user:
data = self.__format_db_file('/root/.config/kylin-config/user.db')
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='i', sender_keyword='sender')
def reset(self,user, id, version, key, sender = None):
self.isAllowedCaller(sender)
success = False
if user == 'root':
success = self._converter.reset('/root/.config/kylin-config/user.db', id, version, key)
else:
data = self.__format_db_file(f'/home/{user}/.config/kylin-config/user.db')
if data == {} or data is None:
return False
success = self._converter.reset(f'/home/{user}/.config/kylin-config/user.db', id, version, key)
if success:
self.key_changed(id, version, key)
tmp = {}
tmp.update(self.__read_only_view)
if tmp == {} or tmp is None:
return False
#将用户配置写入到复制的只读视图里
self.__value_override_default(tmp, data)
for key in tmp:
data = {}
data[key] = tmp[key]
yaml_data = yaml.safe_dump(data,allow_unicode = True)
if yaml_data is None:
continue
with open(f'{path}/{key}.yaml', 'w') as yaml_file:
yaml_file.write(yaml_data)
return True
return success
# 恢复整个id的默认值
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='', out_signature='i', sender_keyword='sender')
def reload(self, sender = None):
self.isAllowedCaller(sender)
success = self._reload()
self.updated() if success else None
return success
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ss', out_signature='b', sender_keyword='sender')
def save(self, user, path, sender = None):
self.isAllowedCaller(sender)
success = False
if user == 'root':
success = self._converter.save('/root/.config/kylin-config/user.db', path)
else:
success = self._converter.save(f'/home/{user}/.config/kylin-config/user.db', path)
return success
#复制old_id的配置到new_id的位置并将新的数据写入到数据库
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='b', sender_keyword='sender')
def extends_id(self, old_id:str, new_id:str, version:str, user:str, sender = None):
self.isAllowedCaller(sender)
success = False
if user == 'root':
success = self._converter.extends_id(old_id, new_id, version, '/root/.config/kylin-config/user.db')
else:
success = self._converter.extends_id(old_id, new_id, version, f'/home/{user}/.config/kylin-config/user.db')
return success
if __name__ == "__main__":
os.makedirs('/etc/kylin-config', exist_ok=True)
logging.basicConfig(filename='/etc/kylin-config/systembus.log',
level=logging.DEBUG,
format='%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger()
# 初始化DBus主循环
DBusGMainLoop(set_as_default=True)
@ -626,4 +189,4 @@ if __name__ == "__main__":
# 开始DBus主循环
mainloop = GLib.MainLoop()
mainloop.run()
mainloop.run()

View File

@ -1,3 +1,4 @@
#!/usr/bin/python3.8
#
# libkysdk-system's Library
#
@ -16,324 +17,90 @@
# You should have received a copy of the GNU General Public License
# along with this library. If not, see <https://www.gnu.org/licenses/>.
#
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
#
#
#!/usr/bin/python3
import os
import logging
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
import conf2Utils
import os, shutil, re
import sqlite3
def __recursive_search__(dictionary, key):
if key in dictionary:
return dictionary[key]
else:
for value in dictionary.values():
if isinstance(value, dict):
result = __recursive_search__(value, key)
if result is not None:
return result
return None
def __write_element_in_table__(version_data:dict ,data: dict, cursor: sqlite3.Cursor, version_id, parent_id):
#key写入到数据库
if 'keys' in data:
keys = data['keys']
for key in keys:
property = key
user_value = keys[key].get('value')
# if attr is None:
# attr = keys[key].get('default')
type = keys[key].get('_type')
default_value = keys[key].get('default')
if isinstance(default_value, str) is False:
default_value = str(default_value)
description = keys[key].get('description')
summary = keys[key].get('summary')
permission = keys[key].get('permission')
if permission is None:
permission = 'public'
#TODO: 计算range取值范围
range = keys[key].get('range')
# reload时没有更新的枚举数据的range应该是枚举参数的字符串列表
# 更新后或初始化时的枚举数据的range是@[枚举名]
if type == 'enum' and isinstance(range, str) and range.startswith('@'):
enum_range = {}
print(keys[key]['range'])
element_list = __recursive_search__(version_data, keys[key]['range'][1:])
for element in element_list:
enum_range[element['nick']] = int(element['value'])
range = str(enum_range)
cursor.execute('''INSERT INTO configures (version_id, property, user_value, data_type, default_value, permission, range, parent, description, summary)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',(version_id, property, user_value, type, default_value, permission, range, parent_id, description, summary))
if 'children' in data:
children = data['children']
for child in children:
if child.startswith('enum_'):
continue
cursor.execute("INSERT INTO configures (version_id,group_name,parent) VALUES (?, ?, ?)",(version_id, child, parent_id))
group_id = cursor.lastrowid
__write_element_in_table__(version_data,children[child],cursor,version_id,group_id)
def __covert_app_table__(data: dict, cursor: sqlite3.Cursor):
# 创建app表
cursor.execute('''CREATE TABLE IF NOT EXISTS app
(id INTEGER PRIMARY KEY AUTOINCREMENT,
app_name TEXT,
defualt_version TEXT)''')
#将app信息写入app表
for app in data.keys():
default_version = data[app].get('default_version')
# 如果没有设置默认版本,将默认版本设置为最大版本
if default_version is None:
for version in data[app]:
if default_version is None:
default_version = version
#比较版本 版本目前认为是2.0.0-0k0格式
default_list = re.findall(r'\d+', default_version)
list = re.findall(r'\d+', version)
for i in range(0,6):
if len(default_list) == i:
default_version = version
break
if len(list) == i:
break
if int(default_list[i]) < int(list[i]):
default_version = version
break
if int(default_list[i]) > int(list[i]):
break
cursor.execute("INSERT INTO app (app_name, defualt_version) VALUES (?,?)",(app, default_version))
def __covert_version_table__(data: dict, cursor: sqlite3.Cursor):
# 创建version表
cursor.execute('''CREATE TABLE IF NOT EXISTS version
(id INTEGER PRIMARY KEY AUTOINCREMENT,
app_id INTEGER,
version TEXT,
compatible TEXT,
FOREIGN KEY (app_id) REFERENCES app(id))''')
for app in data.keys():
cursor.execute("SELECT id FROM app WHERE app_name = ?", (app,))
appId = cursor.fetchone()
for version in data[app].keys():
if(version == 'default_version'):
continue
cursor.execute("INSERT INTO version (app_id,version, compatible) VALUES (?, ?, ?)",(appId[0],version, data[app][version].get('compatible')))
def __covert_configure_table__(data: dict, cursor: sqlite3.Cursor):
# 创建version表
cursor.execute('''CREATE TABLE IF NOT EXISTS configures
(id INTEGER PRIMARY KEY AUTOINCREMENT,
version_id INTEGER,
property TEXT,
group_name TEXT,
user_value TEXT,
data_type TEXT,
default_value TEXT,
permission TEXT,
range TEXT,
parent INTEGER,
description TEXT,
summary TEXT,
FOREIGN KEY (version_id) REFERENCES version(id),
FOREIGN KEY (parent) REFERENCES configures(id))''')
cursor.execute("SELECT * FROM app")
apps = cursor.fetchall()
for app in apps:
cursor.execute("SELECT * FROM version WHERE app_id = ?", (app[0],))
versions = cursor.fetchall()
for version in versions:
version_data = data[app[1]][version[2]]
#keys写入数据库
__write_element_in_table__(version_data,version_data,cursor,version[0],0)
def __dict2db__(dict, path):
try:
# 连接到数据库(如果不存在则创建)
db_file_path = path.rsplit('/',maxsplit=1)[0]
if not os.path.exists(db_file_path):
os.makedirs(db_file_path)
conn = sqlite3.connect(path)
# 创建游标对象
cursor = conn.cursor()
conn.execute('BEGIN TRANSACTION')
# 获取数据库中的所有表名
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = cursor.fetchall()
# 遍历所有表名对每个表执行DELETE语句以删除所有行
for table in tables:
cursor.execute(f"DELETE FROM {table[0]}")
__covert_app_table__(dict,cursor)
__covert_version_table__(dict,cursor)
__covert_configure_table__(dict,cursor)
# 提交更改
conn.commit()
conn.close()
return 0
except Exception as e:
conn.rollback()
conn.close()
return -1
#读取一个元素
def __format_element(parent: dict, cursor: sqlite3.Cursor, version_id, parent_id):
keys = {}
children = {}
cursor.execute('SELECT * FROM configures WHERE version_id = ? AND parent = ?', (version_id,parent_id))
configure_data = cursor.fetchall()
for configure in configure_data:
#读取子分组
if configure[3] is not None:
children[configure[3]] = {}
__format_element(children[configure[3]],cursor,version_id,configure[0])
#读取key
else:
keys[configure[2]] = {}
if configure[4] is not None:
keys[configure[2]]['value'] = configure[4]
if configure[5] is not None:
keys[configure[2]]['_type'] = configure[5]
if configure[6] is not None:
keys[configure[2]]['default'] = configure[6]
if configure[7] is not None:
keys[configure[2]]['permission'] = configure[7]
if configure[8] is not None:
keys[configure[2]]['range'] = configure[8]
if configure[10] is not None:
keys[configure[2]]['description'] = configure[10]
if configure[11] is not None:
keys[configure[2]]['summary'] = configure[11]
if keys:
parent['keys'] = keys
if children:
parent['children'] = children
#将数据库中的内容读取到数据结构中
#由于存储数组到数据库不会存储 枚举 所以反序列化出来的数据结构中不存在 枚举
def __format_db_file(db_file: str):
try:
data = {}
conn = sqlite3.connect(db_file)
if conn is None:
return data
# 创建游标对象
cursor = conn.cursor()
#遍历app表
conn.execute('BEGIN TRANSACTION')
cursor.execute('SELECT * FROM app')
app_data = cursor.fetchall()
for app in app_data:
data[app[1]] = {}
cursor.execute('SELECT * FROM version WHERE app_id = ?', (app[0],))
version_data = cursor.fetchall()
for version in version_data:
data[app[1]][version[2]] = {}
__format_element(data[app[1]][version[2]],cursor,version[0],0)
conn.close()
return data
except Exception as e:
conn.rollback()
conn.close()
return {}
def __merge_dict(dest:dict , src:dict):
if src is None:
return dest
for key, value in src.items():
if key in dest and isinstance(dest[key], dict) and isinstance(src[key], dict):
__merge_dict(dest[key], src[key])
else:
if key != 'user_value':
dest[key] = value
return dest
def __del_discarded_key(dest:dict, src:dict):
keys_to_delete = []
for key in dest:
if not isinstance(dest[key], dict):
return
if key not in src:
keys_to_delete.append(key)
else:
__del_discarded_key(dest[key], src[key])
for key in keys_to_delete:
dest.pop(key)
__user_view = {}
__destination_file = '~/.config/kylin-config/user.db'
logger = None
destination_file = '~/.config/kylin-config/user.db'
class KYSettingsDBusSessionService(dbus.service.Object):
def __init__(self, bus_name, object_path):
logger.info('Session DBus Init')
dbus.service.Object.__init__(self, bus_name, object_path)
conn = dbus.SystemBus()
conn.add_signal_receiver(self._reload_handler,
signal_name='updated',
dbus_interface='com.kylin.kysdk.conf2',
bus_name='com.kylin.kysdk.conf2',
path="/com/kylin/kysdk/conf2")
conn.add_signal_receiver(self._key_changed_handler,
signal_name='key_changed',
dbus_interface='com.kylin.kysdk.conf2',
bus_name='com.kylin.kysdk.conf2',
path="/com/kylin/kysdk/conf2")
self._converter = conf2Utils.Converter(logger)
self.Init()
logger.info('Session DBus end')
def _reload_handler(self):
logger.info('On update')
self.Init()
self.updated()
def _key_changed_handler(self, id, version, key):
logger.info('On key changed')
self._converter.update_user_dict(destination_file)
self.key_changed(id, version, key)
# key值改变信号
@dbus.service.signal("com.kylin.kysdk.conf2", signature='sss')
def key_changed(self, id, version, key):
logger.info(f'emit {key} changed')
# 重载信号
@dbus.service.signal("com.kylin.kysdk.conf2", signature='')
def updated(self):
logger.info('emit updated')
@dbus.service.method("com.kylin.kysdk.conf2")
def Init(self):
try:
source_file = '/etc/kylin-config/user.db'
destination_file = '~/.config/kylin-config/user.db'
destination_file = os.path.expanduser(destination_file)
if os.path.exists(source_file):
if not os.path.exists(destination_file):
os.makedirs(os.path.dirname(destination_file), exist_ok=True)
shutil.copyfile(source_file, destination_file)
except Exception as e:
print(e)
def reload_handler(*args, **kwargs):
data = __format_db_file("/etc/kylin-config/user.db")
__del_discarded_key(__user_view, data)
__merge_dict(__user_view, data)
__dict2db__(__user_view, __destination_file)
self._converter.update_user_db(destination_file)
if __name__ == "__main__":
destination_file = os.path.expanduser(destination_file)
if not os.path.exists(os.path.dirname(destination_file)):
os.makedirs(os.path.dirname(destination_file), mode=0o777, exist_ok=True)
logging.basicConfig(filename=destination_file.replace('user.db', 'sessionbus.log'),
level=logging.DEBUG,
format='%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger()
# 初始化DBus主循环
DBusGMainLoop(set_as_default=True)
try:
__destination_file = os.path.expanduser(__destination_file)
# 连接到DBus系统总线
bus_session = dbus.SessionBus()
bus_session = dbus.SessionBus()
object_path = '/com/kylin/kysdk/conf2'
bus_sesssion_name = dbus.service.BusName("com.kylin.kysdk.conf2", bus = bus_session)
my_dbus_session_service = KYSettingsDBusSessionService(bus_sesssion_name, object_path)
# 注册一个DBus服务
object_path = '/com/kylin/kysdk/conf2'
bus_sesssion_name = dbus.service.BusName("com.kylin.kysdk.conf2", bus = bus_session)
my_dbus_session_service = KYSettingsDBusSessionService(bus_sesssion_name, object_path)
##用户登录,更新用户配置
__user_view = __format_db_file(__destination_file)
reload_handler(None, None)
# 连接到DBus系统总线
bus = dbus.SystemBus()
# 监听DBus信号
bus.add_signal_receiver(reload_handler,
signal_name='updated',
dbus_interface='com.kylin.kysdk.conf2',
bus_name='com.kylin.kysdk.conf2',
path="/com/kylin/kysdk/conf2")
except Exception as e:
print(e)
# 开始DBus主循环
mainloop = GLib.MainLoop()
mainloop.run()

View File

@ -0,0 +1,918 @@
import os
import re
import shutil
import yaml
import sqlite3
import logging
import traceback
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import subprocess
class Converter:
_ro_db = '/etc/kylin-config/user.db'
_ro_dict = {}
_user_dict = {}
def __init__(self, logger:logging.Logger):
self.logger = logger
def update_read_only_db(self):
try:
self._update_table_structure(self._ro_db)
self._creat_db_file(self._ro_db)
self._load_stable_dict()
return self._dict2db(self._ro_dict, self._ro_db)
except:
err_msg = traceback.format_exc()
self.logger.error(f'update_read_only_db {err_msg}')
return False
def update_user_db(self, path):
if not os.path.exists(self._ro_db):
return False
existed = os.path.exists(path)
if not existed:
os.makedirs(os.path.dirname(path), exist_ok=True)
shutil.copyfile(self._ro_db, path)
self._user_dict = self._db2dict(path)
else:
self._update_table_structure(path)
data = self._db2dict(self._ro_db)
self._del_discarded_key(self._user_dict, data)
self._merge_dict(self._user_dict, data)
if os.path.exists(f'{os.path.dirname(path)}/map.yaml'):
self.logger.info("override gsettings config")
with open(f'{os.path.dirname(path)}/map.yaml', 'r') as file:
mmap = yaml.safe_load(file)
if mmap is not None:
for app, gsetting_id in mmap.items():
for version, version_dict in self._user_dict[app].items():
if not isinstance(version_dict, dict):
continue
self._gsettings_config_get(self._user_dict[app][version], gsetting_id)
os.remove(f'{os.path.dirname(path)}/map.yaml')
if path.startswith('/root') and not existed:
return True
if path.startswith('/home'):
self._load_mutable_dict(os.path.dirname(path))
self._dict2db(self._user_dict, path)
return True
def update_user_dict(self, path):
self._user_dict = self._db2dict(path)
def set(self, path, id, version, key, value):
try:
self.logger.info(f'set begin')
# 修改用户配置文件,写入到数据库
group_list = id.split('.')
conn = sqlite3.connect(path)
cursor = conn.cursor()
# 开始写入事务
conn.execute('BEGIN TRANSACTION')
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
app_id = cursor.fetchone()[0]
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id, version))
version_id = cursor.fetchone()[0]
# 查找组
parent_id = 0
for group_name in group_list[1:]:
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'schema'", (version_id, parent_id, group_name))
parent_id = cursor.fetchone()[0]
cursor.execute("UPDATE configures SET custom_value = ? WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'key'", (value, version_id, parent_id, key))
conn.commit()
conn.close()
tmp = self._user_dict[group_list[0]][version]
for group in group_list[1:]:
tmp = tmp[group]
tmp[key]['_value'] = value
self.logger.info(f'set end')
return True
except Exception as e:
conn.rollback()
conn.close()
err_msg = traceback.format_exc()
self.logger.error(f'set {err_msg}')
return False
def reset(self, path, id, version, key):
try:
self.logger.info(f'reset begin')
# 修改用户配置文件,写入到数据库
group_list = id.split('.')
conn = sqlite3.connect(path)
cursor = conn.cursor()
# 开始写入事务
conn.execute('BEGIN TRANSACTION')
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
app_id = cursor.fetchone()[0]
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id,version))
version_id = cursor.fetchone()[0]
# 查找组
parent_id = 0
for group_name in group_list[1:]:
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'schema'", (version_id, parent_id, group_name))
parent_id = cursor.fetchone()[0]
cursor.execute("UPDATE configures SET custom_value = NULL WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'key'", (version_id, parent_id, key))
conn.commit()
conn.close()
tmp = {}
tmp = self._user_dict[group_list[0]][version]
for group in group_list[1:]:
tmp = tmp[group]
if '_value' in tmp[key]:
tmp[key].pop('_value')
self.logger.info(f'reset end')
return True
except Exception as e:
conn.rollback()
conn.close()
err_msg = traceback.format_exc()
self.logger.error(f'set {err_msg}')
return False
def save(self, db_file, dest_path):
try:
self.logger.info(f'save begin')
if not os.path.exists(dest_path):
self.logger.error(f'{dest_path} not exists')
return False
data = self._db2dict(db_file)
if data == {}:
self.logger.error(f'read sqlite failed')
return False
#将用户配置写入到复制的只读视图里
self._value_override_default(data)
for key in data:
with open(f'{dest_path}/{key}.yaml', 'w') as yaml_file:
yaml_file.write(yaml.safe_dump({key:data[key]}, allow_unicode = True))
self.logger.info(f'save end')
return True
except Exception as e:
err_msg = traceback.format_exc()
self.logger.error(f'save {err_msg}')
return False
# 用于kconf2-editor保存文件仅有普通用户权限root用户没有图形化界面
def editor_save(self, data, dest_path):
try:
self.logger.info(f'editor_save begin')
#将用户配置写入到复制的只读视图里
self._value_override_default(data)
for key in data:
with open(f'{dest_path}/{key}.yaml', 'w') as yaml_file:
yaml_file.write(yaml.safe_dump({key:data[key]}, allow_unicode = True))
self.logger.info(f'editor_save end')
return True
except Exception as e:
err_msg = traceback.format_exc()
self.logger.error(f'editor_save {err_msg}')
return False
def extends_id(self, old_id:str, new_id:str, version:str, target_file):
try:
self.logger.info(f'extends_id begin')
target_view = self._db2dict(target_file)
#获取app的引用
list = old_id.split('.', -1)
app = target_view.get(list[0])
if app is None:
self.logger.error(f'{old_id} is not exists')
return False
#获取目标版本的引用,如果为空,获取默认版本
if version == '':
old_data = app[app['_default_version']]
else:
old_data = app.get(version)
if old_data is None:
self.logger.error(f'{version} is not invalid')
for iter in list[1:]:
old_data = old_data.get(iter)
if old_data is None:
self.logger.error(f'{old_id} is not exists')
return False
tmp = {}
tmp.update(old_data)
list = new_id.split('.', -1)
new_data = target_view.get(list[0])
if new_data != app:
self.logger.error(f'{new_id} is invalid')
if version == '':
new_data = app[app['_default_version']]
else:
new_data = app.get(version)
for iter in list[1:]:
if iter not in new_data:
new_data[iter] = {}
new_data = new_data[iter]
new_data.update(tmp)
new_data['_extends'] = old_id
self.logger.info(f'extends_id end')
return self._dict2db(target_view, target_file)
except Exception as e:
err_msg = traceback.format_exc()
self.logger.error(f'extends_id {err_msg}')
return False
def load_dirs_config(self, dirs:list) -> dict:
try:
result = {}
for dir in dirs:
list = self._sort_diretory(dir)
for file in list:
# self.logger.info('Read conifg file')
data = self._load_one_file(f'{dir}/{file}')
# self.logger.info('Read conifg file')
if not data:
continue
# self.logger.info('Merger in view')
is_group_file = False
for value in data.values():
if isinstance(value, dict):
is_group_file = True if '_default' in next(iter(value.values())) else False
break
if is_group_file:
self._common_override_by_final(result, data)
else:
self._merge_dict_by_final(result, data)
# self.logger.info('Merger in view end')
return result
except:
return {}
def _load_stable_dict(self):
self.logger.info('Read stable dirs')
self._ro_dict.clear()
with open('/etc/kylin-config/conf2.yaml', 'r') as file:
configures = yaml.safe_load(file)
for dir in configures['dirs']:
list = self._sort_diretory(f'/etc/kylin-config/{dir}')
for file in list:
# self.logger.info('Read conifg file')
data = self._load_one_file(f'/etc/kylin-config/{dir}/{file}')
# self.logger.info('Read conifg file')
if not data:
continue
# self.logger.info('Merger in view')
is_group_file = False
for value in data.values():
if isinstance(value, dict):
is_group_file = True if '_default' in next(iter(value.values())) else False
break
if is_group_file:
self._common_override_by_final(self._ro_dict, data)
else:
self._merge_dict_by_final(self._ro_dict, data)
# self.logger.info('Merger in view end')
self.logger.info('Read stable dirs end')
def _load_mutable_dict(self, dir):
self.logger.info('Read mutable dirs')
list = self._sort_diretory(f'{dir}/configs')
for file in list:
# self.logger.info('Read conifg file')
data = self._load_one_file(f'{dir}/configs/{file}')
# self.logger.info('Read conifg file')
if not data:
continue
# self.logger.info('Merger in view')
is_group_file = False
for value in data.values():
if isinstance(value, dict):
is_group_file = True if '_default' in next(iter(value.values())) else False
break
if is_group_file:
self._common_override_by_stable(self._user_dict, data)
else:
self._merge_dict_by_stable(self._user_dict, data)
# self.logger.info('Merger in view end')
self.logger.info('Read mutable dirs end')
# 按规范对文件名进行排序
def _sort_diretory(self, yaml_dir):
if not os.path.exists(yaml_dir):
return []
# 获取目录内所有文件名
file_list = os.listdir(yaml_dir)
# 定义排序函数
def custom_sort(file_name):
match = re.match(r"(\d+)?-?(.*)", file_name)
if match.group(1):
return (int(match.group(1)), match.group(2))
else:
return (0, match.group(2))
sorted_file_list = sorted(file_list, key=custom_sort)
return sorted_file_list
# 读取一个文件
def _load_one_file(self, file:str):
chinese_pattern = re.compile(u'[\u4e00-\u9fa5]+')
if bool(chinese_pattern.search(file)) or file.startswith('.'):
return {}
yaml_data = {}
if file.endswith('.yaml'):
with open(file,'r') as stream:
yaml_data = yaml.safe_load(stream)
if yaml_data is None:
self.logger.error(f'Load {file} failed. Check the text formatting')
return {}
return yaml_data
# 合并两个字典
def _merge_dict(self, dest:dict , src:dict):
if src == {}:
return
if dest == {}:
dest.update(src)
return
for key in src.keys():
if key in dest :
if isinstance(dest[key], dict) and isinstance(src[key], dict):
self._merge_dict(dest[key], src[key])
else:
dest[key] = src[key]
else:
dest[key] = src[key]
return
# 合并两个字典, 处理final权限
def _merge_dict_by_final(self, dest:dict , src:dict):
if src == {}:
return
if dest == {}:
dest.update(src)
return
if '_permission' in dest:
if dest['_permission'] == 'final':
return
for key in src.keys():
if key in dest :
if isinstance(dest[key], dict) and isinstance(src[key], dict):
self._merge_dict_by_final(dest[key], src[key])
else:
dest[key] = src[key]
else:
dest[key] = src[key]
return
# 合并两个字典, 处理stable权限
def _merge_dict_by_stable(self, dest:dict , src:dict):
if src == {}:
return
if dest == {}:
dest.update(src)
return
if '_permission' in dest:
if dest['_permission'] == 'final' or dest['_permission'] == 'stable':
return
for key in src.keys():
if key in dest :
if isinstance(dest[key], dict) and isinstance(src[key], dict):
self._merge_dict_by_stable(dest[key], src[key])
else:
dest[key] = src[key]
else:
dest[key] = src[key]
return
# 全局配置字典覆盖,处理final权限
def _common_override_by_final(self, dest:dict, src:dict):
for app in dest:
for version in dest[app]:
for group in dest[app][version]:
if group in src:
self._merge_dict_by_final(dest[app][version][group], src[group])
# 全局配置字典覆盖,处理stable权限
def _common_override_by_stable(self, dest:dict, src:dict):
for app in dest:
for version in dest[app]:
for group in dest[app][version]:
if group in src:
self._merge_dict_by_stable(dest[app][version][group], src[group])
# 字典写入到数据库
def _dict2db(self, dict:dict, path:str):
try:
self.logger.info('write config in database')
conn = sqlite3.connect(path)
cursor = conn.cursor()
conn.execute('BEGIN TRANSACTION')
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = cursor.fetchall()
# 遍历所有表名对每个表执行DELETE语句以删除所有行
for table in tables:
cursor.execute(f"DELETE FROM {table[0]}")
app_id = 0
version_id = 0
apps = list(dict.keys())
for i in range(0, len(apps)):
app = apps[i]
app_id = app_id + 1
default_version = self._calculate_default_version(dict[app])
cursor.execute("INSERT INTO app (app_name, default_version) VALUES (?,?)",(app, default_version))
versions = list(dict[app].keys())
for j in range(0, len(versions)):
version = versions[j]
if version == '_default_version':
continue
version_id = version_id + 1
cursor.execute("INSERT INTO version (app_id, version, compatible) VALUES (?, ?, ?)",
(app_id, version, dict[app][version].get('_compatible')))
configures = dict[app][version]
self._write_group_in_db(configures, configures, cursor, version_id, 0)
conn.commit()
conn.close()
self.logger.info('write config in database end')
return True
except:
err_msg = traceback.format_exc()
self.logger.error(f'_dict2db {err_msg}')
conn.rollback()
conn.commit()
return False
# 计算默认版本
def _calculate_default_version(self, data:dict):
versions = list(data.keys())
if '_default_version' in versions:
return data.get('_default_version')
default_version = ''
for version in versions:
if default_version == '':
default_version = version
continue
default_nums = re.findall(r'\d+', default_version)
nums = re.findall(r'\d+', version)
for i in range(0, 6):
if nums[i] > default_nums[i]:
default_version = version
break
return default_version
#递归写入组到configures表
def _write_group_in_db(self, version_data:dict, data: dict, cursor: sqlite3.Cursor, version_id, parent_id):
groups = []
for key, value in data.items():
if isinstance(value, dict):
if(value.get('_default') is None):
groups.append(key)
else:
self._write_key_in_db(version_data, key, value, cursor, version_id, parent_id, data.get('_permission'))
for group in groups:
node_name = group
node_type = 'schema'
permission = data[group].get('_permission')
if permission is None:
permission = 'public'
description = data[group].get('_description')
summary = data[group].get('_summary')
extends = data[group].get('_extends')
cursor.execute('''INSERT INTO configures
(version_id, node_name, node_type, permission, description, summary, parent, extends)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
(version_id, node_name, node_type, permission, description, summary, parent_id, extends))
group_id = cursor.lastrowid
self._write_group_in_db(version_data, data[group], cursor, version_id, group_id)
# 写入键的数据到configures表内
def _write_key_in_db(self, version_data:dict, key:str, value:dict, cursor: sqlite3.Cursor, version_id, parent_id, parent_permission):
node_name = key
node_type = 'key'
permission = value.get('_permission')
if permission is None:
if parent_permission is None:
permission = 'public'
else:
permission = parent_permission
description = value.get('_description')
summary = value.get('_summary')
value_type = value.get('_type')
custom_value = value.get('_value')
default_value = value.get('_default')
if isinstance(default_value, bool):
default_value = 'true' if default_value else 'false'
range = value.get('_range')
if value_type == 'enum' and isinstance(range, str) and range.startswith('@'):
enum_range = {}
element_list = self._recursive_search(version_data, value['_range'][1:])
for element in element_list:
num = element['_value']
if isinstance(num, str):
if num.startswith('0x'):
num = int(num, 16)
else:
num = int(num, 10)
enum_range[element['_nick']] = num
range = str(enum_range)
cursor.execute('''INSERT INTO configures
(version_id, node_name, node_type, permission, description, summary, parent, value_type, custom_value, default_value, range)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
(version_id, node_name, node_type, permission, description, summary, parent_id, value_type, custom_value, default_value, range))
# 查询枚举类型数据的枚举定义
def _recursive_search(self, dictionary, key):
if key in dictionary:
return dictionary[key]
else:
for value in dictionary.values():
if isinstance(value, dict):
result = self._recursive_search(value, key)
if result is not None:
return result
return None
# 读数据库数据到字典
def _db2dict(self, path):
try:
conn = sqlite3.connect(path)
cursor = conn.cursor()
cursor.execute('SELECT * FROM app')
apps = cursor.fetchall()
cursor.execute('SELECT * FROM version')
versions = cursor.fetchall()
cursor.execute('SELECT * FROM configures')
configures = cursor.fetchall()
conn.close()
data = {}
stack = []
i = j = k = 0
for i in range(len(apps)):
app = apps[i][1]
app_id = i + 1
default_value = apps[i][2]
data[app] = {}
if(default_value):
data[app]['_default_version'] = default_value
for j in range(j, len(versions)):
# app_id改变退出版本循环
version_app_id = versions[j][1]
if version_app_id != app_id:
break
version = versions[j][2]
data[app][version] = {}
if versions[j][3]:
data[app][version]['compatible'] = versions[j][3]
stack.append((0, data[app][version]))
# 如果占用内存过大,可以改为在这里读取对应版本的所有配置
# 不再保存k值每次循环从0开始
for k in range(k, len(configures)):
# version_id改变退出循环
if configures[k][1] != j + 1:
stack.clear()
break
while configures[k][7] != stack[-1][0]:
stack.pop()
node_name = configures[k][2]
node_type = configures[k][3]
permission = configures[k][4]
description = configures[k][5]
summary = configures[k][6]
value_type = configures[k][8]
custom_value = configures[k][9]
default_value = configures[k][10]
value_range = configures[k][11]
extends = configures[k][12]
if node_type == 'schema':
tmp = stack[-1][1]
tmp[node_name] = {}
stack.append((configures[k][0], tmp[node_name]))
if permission is not None:
tmp[node_name]['_permission'] = permission
if description is not None:
tmp[node_name]['_description'] = description
if summary is not None:
tmp[node_name]['_summary'] = summary
if extends is not None:
tmp[node_name]['_extends'] = extends
elif node_type == 'key':
tmp = stack[-1][1]
tmp[node_name] = {}
if permission is not None:
tmp[node_name]['_permission'] = permission
if description is not None:
tmp[node_name]['_description'] = description
if summary is not None:
tmp[node_name]['_summary'] = summary
if value_type is not None:
tmp[node_name]['_type'] = value_type
if custom_value is not None:
tmp[node_name]['_value'] = custom_value
if default_value is not None:
tmp[node_name]['_default'] = default_value
if value_range is not None:
tmp[node_name]['_range'] = value_range
return data
except:
err_msg = traceback.format_exc()
self.logger.error(f'_db2dict {err_msg}')
return {}
# 删除dest中存在但不存在与src中的键或组
def _del_discarded_key(self, dest:dict, src:dict):
keys_to_delete = []
for key in dest:
if not isinstance(dest[key], dict):
continue
if key not in src:
if dest[key].get('_extends') is None:
keys_to_delete.append(key)
else:
self._del_discarded_key(dest[key], src[key])
for key in keys_to_delete:
dest.pop(key)
# 导出时使用value的值替带default值
def _value_override_default(self, data:dict):
for key, value in data.items():
if isinstance(value, dict):
self._value_override_default(value)
else:
if '_value' in data:
data['_default'] = data.pop('_value')
return
def _creat_db_file(self, path):
conn = sqlite3.connect(path)
cursor = conn.cursor()
conn.execute('BEGIN TRANSACTION')
cursor.execute('''CREATE TABLE IF NOT EXISTS app
(id INTEGER PRIMARY KEY AUTOINCREMENT,
app_name TEXT,
default_version TEXT)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS version
(id INTEGER PRIMARY KEY AUTOINCREMENT,
app_id INTEGER,
version TEXT,
compatible TEXT,
FOREIGN KEY (app_id) REFERENCES app(id))''')
cursor.execute('''CREATE TABLE IF NOT EXISTS configures
(id INTEGER PRIMARY KEY AUTOINCREMENT,
version_id INTEGER,
node_name TEXT,
node_type TEXT,
permission TEXT,
description TEXT,
summary TEXT,
parent INTEGER,
value_type TEXT,
custom_value TEXT,
default_value TEXT,
range TEXT,
extends TEXT,
FOREIGN KEY (version_id) REFERENCES version(id),
FOREIGN KEY (parent) REFERENCES configures(id))''')
conn.commit()
conn.close()
def _gsettings_config_get(self, data, id):
for key, value in data.items():
if not isinstance(value, dict):
continue
if '_default' in value:
result = subprocess.run(['gsettings','get', id, key], capture_output=True, text=True)
custom_value = result.stdout.strip()
custom_value = custom_value.split(' ')[-1] if custom_value.startswith('@') else custom_value
value['_value'] = custom_value
else:
self._gsettings_config_get(value, f'{id}.{key}')
def _update_table_structure(self, path):
try:
if not os.path.exists(path):
return True
conn = sqlite3.connect(path)
cursor = conn.cursor()
cursor.execute('BEGIN TRANSACTION')
# 检查是否是旧的表结构
is_old = False
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='configures';")
table_exists = cursor.fetchone()
if table_exists:
cursor.execute("PRAGMA table_info(configures);")
columns = cursor.fetchall()
for column in columns:
if column[1] == 'group_name':
is_old = True
break
if is_old:
self.logger.info('Data base table is old structure. Update structure')
# 如果是基础数据库,直接删掉重新生成
if path == self._ro_db:
os.remove(path)
else:
cursor.execute('''CREATE TABLE IF NOT EXISTS new_configures
(id INTEGER PRIMARY KEY AUTOINCREMENT,
version_id INTEGER,
node_name TEXT,
node_type TEXT,
permission TEXT,
description TEXT,
summary TEXT,
parent INTEGER,
value_type TEXT,
custom_value TEXT,
default_value TEXT,
range TEXT,
extends TEXT,
FOREIGN KEY (version_id) REFERENCES version(id),
FOREIGN KEY (parent) REFERENCES configures(id))''')
cursor.execute("INSERT INTO new_configures (version_id, node_name, node_type, permission, description, summary, parent, value_type, custom_value, default_value, range, extends) SELECT "
"version_id,"
"CASE "
"WHEN property IS NOT NULL THEN property "
"WHEN group_name IS NOT NULL THEN group_name "
"END, "
"CASE "
"WHEN property IS NOT NULL THEN 'key' "
"WHEN group_name IS NOT NULL THEN 'schema' "
"END,"
"permission,"
"description,"
"summary,"
"parent,"
"data_type,"
"user_value,"
"default_value,"
"range,"
"extends "
"FROM configures;")
# 删除原表
cursor.execute("DROP TABLE configures;")
# 将新表重命名为原表的名称
cursor.execute("ALTER TABLE new_configures RENAME TO configures;")
conn.commit()
conn.close()
return True
except Exception as e:
err_msg = traceback.format_exc()
self.logger.error(f'{err_msg}')
return False
class FileWatche:
class MyHandler(FileSystemEventHandler):
def __init__(self, server):
self._server = server
def on_modified(self, event):
if event.is_directory:
return
self._server.reload()
def on_created(self, event):
if event.is_directory or not os.path.dirname(event.src_path) == '/etc/kylin-config/basic':
return
gsettings_id = os.path.basename(event.src_path).strip(".yaml")
mmap = {}
with open(event.src_path, 'r') as file:
data = yaml.safe_load(file)
for app, version in data.items():
if not isinstance(version, dict):
continue
mmap[app] = gsettings_id
home_directories = [os.path.expanduser('~' + username) for username in os.listdir('/home')]
home_directories.append('/root')
for home_dir in home_directories:
file_path = os.path.join(home_dir, '.config/kylin-config/map.yaml')
if not os.path.exists(os.path.dirname(file_path)):
continue
# file_path = '/home/kylin/test.yaml'
if os.path.exists(file_path):
with open(file_path, 'r') as file:
tmp = yaml.safe_load(file)
if tmp is not None:
mmap.update(tmp)
os.remove(file_path)
with open(file_path, 'w') as file:
file.write(yaml.safe_dump(mmap))
os.chmod(file_path, 0o666)
def __init__(self, path, server) -> None:
self._server = server
self._observer = Observer()
self._event_handler = FileWatche.MyHandler(server)
self._observer.schedule(self._event_handler, path, recursive=False)
self._observer.start()
def stopWatche(self):
if self._observer.isAlive():
self._observer.stop()
self._observer.join()

View File

@ -1,14 +1,14 @@
[Unit]
Description=KYLIN CONF2 DBUS
Wants=systemd-logind.service
Before=systemd-logind.service
Wants=systemd-logind.service lightdm.service
Before=systemd-logind.service lightdm.service
[Service]
Type=dbus
Restart=always
RestartSec=1
BusName=com.kylin.kysdk.conf2
ExecStart=python3 /usr/bin/conf2-server.py
ExecStart=/usr/bin/conf2-server.py
[Install]
WantedBy=multi-user.target

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +0,0 @@
find_package(PkgConfig REQUIRED)
pkg_check_modules(CONF2 REQUIRED kysdk-conf2)
include_directories(${CONF2_INCLUDE_DIRS})
add_executable(kyconf2-test kyconf2-test.c)
target_link_libraries(kyconf2-test ${CONF2_LIBRARIES})
install(TARGETS kyconf2-test
DESTINATION /usr/bin)

View File

@ -1,402 +0,0 @@
control-center:
3.20.1.31-0k2.11:
children:
powermanager:
keys:
sleep:
_type: b
default: 'true'
dormant:
_type: b
default: 'true'
shutdown:
_type: b
default: 'true'
switch-user:
_type: b
default: 'true'
apt:
children:
proxy:
keys:
enabled:
_type: b
default: 'false'
description: This key is used to control whether to open apt-proxy.
summary: Whether open
host:
_type: s
default: ''
description: The machine name to proxy APT through.
summary: APT proxy host name
port:
_type: i
default: '8080'
description: "The port on the machine defined by “/apt/proxy/host”\
\ that you\n proxy through."
range: 0,65535
summary: APT proxy port
desktop:
keys:
computer-icon-locking:
_type: b
default: 'true'
description: Whether lock computer icon on start menu or not.
summary: Lock computer icon on start menu
computer-icon-visible:
_type: b
default: 'true'
description: Whether show computer icon on desktop or not.
summary: Show computer icon on desktop
home-icon-visible:
_type: b
default: 'true'
description: Whether show home icon on desktop or not.
summary: Show home icon on desktop
menufull-screen:
_type: b
default: 'false'
description: Whether to always use the start menu in full screen.
summary: menufull-screen switch button
network-icon-visible:
_type: b
default: 'true'
description: Whether show network icon on desktop or not.
summary: Show network icon on desktop
personal-icon-locking:
_type: b
default: 'false'
description: Whether personal icon on start menu or not.
summary: Lock personal icon on start menu
settings-icon-locking:
_type: b
default: 'true'
description: Whether lock settings icon on start menu or not.
summary: Lock settings icon on start menu
trash-icon-locking:
_type: b
default: 'false'
description: Whether lock trash icon on start menu or not.
summary: Lock trash icon on start menu
trash-icon-visible:
_type: b
default: 'true'
description: Whether show trash icon on desktop or not.
summary: Show trash icon on desktop
volumes-visible:
_type: b
default: 'true'
description: Whether show volumes icon on desktop or not.
summary: Show volumes icon on desktop
enum_org.ukui.control-center.noticeorigin.Type:
- nick: none
value: '0'
- nick: corner
value: '1'
- nick: all
value: '2'
experienceplan:
keys:
join:
_type: b
default: 'true'
description: Whether this plugin would be activated by ukui-settings-daemon
or not
summary: join user experience plan
keybinding:
keys:
action:
_type: s
default: ''
description: Command associated with a custom keybinding.
summary: Command
binding:
_type: s
default: ''
description: Keybinding associated with a custom shortcut.
summary: Keybinding
name:
_type: s
default: ''
description: Description associated with a custom keybinding.
summary: Name
keyboard: {}
notice:
keys:
blacklist:
_type: as
default: '[]'
description: Hidden DektopList
summary: ''
enable-notice:
_type: b
default: 'true'
description: Whether an OSD notification is shown to notify about changes
summary: Show OSD notification
iscn-env:
_type: b
default: 'true'
description: Determine whether the environment is Chinese
summary: ''
show-new-feature:
_type: b
default: 'true'
description: Whether this plugin would be activated by ukui-settings-daemon
or not
summary: Activation of this plugin
show-on-lockscreen:
_type: b
default: 'true'
description: Binding to eject an optical disc.
summary: Eject
noticeorigin:
keys:
maximize:
_type: i
default: '3'
description: The maximize num of messages on notice window.
summary: maximize num of messages
messages:
_type: b
default: 'true'
description: .
summary: messages notice
name-cn:
_type: s
default: ''
description: The name passed to the sidebar
summary: app's name
name-us:
_type: s
default: ''
description: The name passed to the sidebar
summary: app's name
notification-style:
_type: s
default: mutative
description: 'Select the notification style. Supported values are "none",
"mutative","always".
If this is "none", notifications don''t show up on the screen,
but go to the notification center
If this is "mutative", show on the upper right corner of the screen,
it will disappear automatically.
If this is "always", remain on the screen until turned off.'
summary: The display style of the notification
show-detail:
_type: b
default: 'false'
description: Whether the notification show detail on screenlock
summary: ''
show-on-screenlock:
_type: b
default: 'false'
description: Whether the notification show on screenlock
summary: ''
type:
_type: enum
default: corner
description: the type of notice in system.
range: '@enum_org.ukui.control-center.noticeorigin.Type'
summary: type of notice message
voice:
_type: b
default: 'true'
description: .
summary: voice notice
osd:
keys:
show-lock-tip:
_type: b
default: 'true'
description: show keyboard tip or not. eg. Caps Lock. Num Lock
summary: show keyboard tip
panel:
children:
plugins:
keys:
calendar:
_type: s
default: lunar
description: calendar system used in UKUI Desktop Environment ,ontrol
by ukui-panel and ukui-control-center
summary: Lunar calendar
date:
_type: s
default: cn
description: date format
summary: date formate
firstday:
_type: s
default: monday
description: Select the first day of the week
summary: first of week
hoursystem:
_type: s
default: '24'
description: hoursystem used in UKUI Desktop Environment ,ontrol by
ukui-panel and ukui-control-center
summary: HourSystem status
nightmodestatus:
_type: b
default: 'false'
description: ''
summary: ukui-control-center sets the night mode status so that ukui-panel
can get the status
ntp:
_type: s
default: ''
description: user-defined ntp server address
summary: customize ntp server address
showlanguage:
_type: as
default: '[]'
description: show language in plugin area
summary: show language in plugin area
synctime:
_type: b
default: 'true'
description: ''
summary: sync time from network
themebynight:
_type: b
default: 'false'
description: ''
summary: ukui-control-center theme changes follow with the night
mode
time:
_type: s
default: '24'
description: Select the first day of the week
summary: first of week
timezones:
_type: as
default: '[]'
description: other time zones
summary: all time zones of time display
personalise:
keys:
blurry:
_type: i
default: '3'
description: 1- Low effect;2-Middle effect;3-High effect
summary: Control the frosted glass effect of the component
custompower:
_type: b
default: 'false'
description: Used to determine that the control panel user has customized
a power plan
summary: Whether to customize the power plan
effect:
_type: b
default: 'true'
description: 'ture:Special effects open; false: Special effects off'
summary: Control panel special effects transmit signal
save-transparency:
_type: i
default: '100'
description: Save the transparency before the special effects mode is
turned off
summary: Save the transparency before the special effects mode is turned
off
transparency:
_type: d
default: '0.65'
description: Control the transparency of all components
summary: Control the transparency of all components
plugins:
keys:
plugin-name:
_type: s
default: ''
description: the name to match status
summary: plugin's name
show:
_type: b
default: 'true'
description: .
summary: whether the plugin's status
pluginstatus: {}
wifi:
children:
switch:
keys:
switch:
_type: b
default: 'true'
description: wifi switch
summary: wifi switch
switchor:
_type: b
default: 'true'
description: wifi switch of kylin network manager
summary: wifi switchor
wificard:
_type: b
default: 'true'
description: Determine if the wireless network card is inserted
summary: Wireless network card
keys:
fonts-list:
_type: as
default: '[''CESI仿宋-GB13000'',''CESI_FS_GB13000'', ''CESI仿宋-GB18030'',''CESI_FS_GB18030'',
''CESI仿宋-GB2312'',''CESI_FS_GB2312'', ''CESI宋体-GB13000'',''CESI_SS_GB13000'',
''CESI宋体-GB18030'',''CESI_SS_GB18030'', ''CESI宋体-GB2312'',''CESI_SS_GB2312'',
''CESI小标宋-GB13000'',''CESI_XBS_GB13000'', ''CESI小标宋-GB18030'',''CESI_XBS_GB18030'',
''CESI小标宋-GB2312'',''CESI_XBS_GB2312'', ''CESI楷体-GB13000'',''CESI_KT_GB13000'',
''CESI楷体-GB18030'',''CESI_KT_GB18030'', ''CESI楷体-GB2312'',''CESI_KT_GB2312'',
''CESI黑体-GB13000'',''CESI_HT_GB13000'', ''CESI黑体-GB18030'',''CESI_HT_GB18030'',
''CESI黑体-GB2312'',''CESI_HT_GB2312'', ''仿宋'', ''黑体'', ''楷体'', ''宋体'', ''华文彩云'',''STCaiyun'',
''华文仿宋'',''STFangsong'', ''华文琥珀'',''STHupo'', ''华文楷体'',''STKaiti'', ''华文隶书'',''STLiti'',
''华文宋体'',''STSong'', ''华文细黑'',''STXihei'', ''华文行楷'',''STXingkai'', ''华文新魏'',''STXinwei'',
''Noto Sans CJK SC'', ''Noto Sans CJK SC Black'', ''Noto Sans Mono CJK SC'',
''Noto Sans CJK SC DemiLight'', ''Noto Sans CJK SC Light'', ''Noto Sans
CJK SC Medium'', ''Noto Sans CJK SC'', ''Noto Sans CJK SC Thin'',''Dotted
Songti Square'',''WenQuanYi Bitmap Song'']'
description: Control panel default font list
summary: Control panel default font list
2.0.0.0-0k0.0:
children:
powermanager:
keys:
sleep:
_type: b
default: 'true'
dormant:
_type: b
default: 'true'
shutdown:
_type: b
default: 'true'
switch-user:
_type: b
default: 'true'
apt:
children:
proxy:
keys:
enabled:
_type: b
default: 'false'
description: This key is used to control whether to open apt-proxy.
summary: Whether open
host:
_type: s
default: ''
description: The machine name to proxy APT through.
summary: APT proxy host name
port:
_type: i
default: '8080'
description: "The port on the machine defined by “/apt/proxy/host”\
\ that you\n proxy through."
range: 0,65535
summary: APT proxy port

View File

@ -18,72 +18,318 @@
*
*/
#include "../api/libkysettings.h"
#include <stdio.h>
#include <unistd.h>
#include <glib-2.0/glib.h>
//键值改变信号回调函数
// 键值改变信号回调函数
static void on_key_changed(KSettings *setting, char *key, void *user_data)
{
printf("on key change signal\n");
char *value = kdk_conf2_get_value(setting, key);
printf("%s change to %s\n", key, value);
}
// 键值改变信号回调函数
static void on_reload(KSettings *setting, void *user_data)
{
printf("reload signal\n");
}
int main(int argc, char *argv[])
{
KSettings *setting = kdk_conf2_new("systemd.powermanager", NULL);
if(NULL == setting)
KSettings *setting = kdk_conf2_new("test.notice", NULL);
if (NULL == setting)
{
printf("get handle failed\n");
return 0;
}
//链接键值改变信号
/**
*
*
*/
// kdk_conf2_connect_signal(setting, "changed::sleep", on_key_changed, NULL);
// kdk_conf2_connect_signal(setting, "changed::int", on_key_changed, NULL);
//读配置
char *value = kdk_conf2_get_value(setting, "sleep");
if(NULL != value)
char *schema_summary = kdk_conf2_get_schema_summary(setting);
if (schema_summary)
{
printf("sleep user value: %s\n", value);
free(value);
printf("test.notice summary\t: %s\n", schema_summary);
free(schema_summary);
}
//读默认配置
value = kdk_conf2_get_default_value(setting, "sleep");
if (NULL != value)
char *schema_description = kdk_conf2_get_schema_desription(setting);
if (schema_description)
{
printf("sleep default value: %s\n", value);
free(value);
printf("test.notice description\t: %s\n", schema_description);
free(schema_description);
}
//读对应数据类型的值
//调用获取对应数据类型的接口前调用has_key确保键存在。否则无法保证返回值的准确性
if(kdk_conf2_has_key(setting, "sleep"))
char *id = kdk_conf2_get_id(setting);
if (id)
{
int b_sleep = kdk_conf2_get_boolean(setting, "sleep");
printf("sleep user boolean: %s\n", b_sleep ? "true" : "false");
b_sleep = kdk_conf2_get_default_boolean(setting, "sleep");
printf("sleep defalut boolean: %s\n", b_sleep ? "true" : "false");
printf("id is\t: %s\n", id);
free(id);
}
//设置键值
int success = kdk_conf2_set_value(setting, "sleep", "true");
if(0 == success)
char *version = kdk_conf2_get_version(setting);
if (version)
{
printf("set value failed\n");
printf("version is\t: %s\n", version);
free(version);
}
//其它接口参考头文件或接口文档
char **children = kdk_conf2_list_children(setting);
if (children)
{
printf("children:\n");
for (int i = 0; children[i]; i++)
{
printf("\t%s\n", children[i]);
free(children[i]);
}
free(children);
}
usleep(10);
//注销句柄
char **keys = kdk_conf2_list_keys(setting);
if (keys)
{
printf("keys:\n");
for (int i = 0; keys[i]; i++)
{
printf("\t%s\n", keys[i]);
free(keys[i]);
}
free(keys);
}
// 把childname替换为正确的子组名
KSettings *child = kdk_conf2_get_child(setting, "proxy");
if (child)
{
printf("get child :test.notice.proxy\n");
}
char *range = kdk_conf2_get_range(setting, "type");
if (range)
{
printf("Type range is %s\n", range);
free(range);
range = NULL;
}
int success = 0;
success = kdk_conf2_range_check(setting, "int", "65540");
printf("value is %s\n", success ? "valid" : "invalid");
{
/**********通用读写**********/
char *value = kdk_conf2_get_default_value(setting, "int");
if (NULL != value)
{
printf("Int default value: %s\n", value);
free(value);
}
value = kdk_conf2_get_value(setting, "int");
if (NULL != value)
{
printf("Int value: %s\n", value);
free(value);
}
success = kdk_conf2_set_value(setting, "int", "8081");
if (0 == success)
{
printf("set int failed\n");
}
/**********枚举读写**********/
int e = kdk_conf2_get_default_enum(setting, "type");
printf("Type default value is %d\n", e);
e = kdk_conf2_get_enum(setting, "type");
printf("Type value is %d\n", e);
success = kdk_conf2_set_enum(setting, "type", 0x2);
if (0 == success)
{
printf("set type failed\n");
}
/**********整形读写**********/
int i = kdk_conf2_get_default_int(setting, "int");
printf("Int default value is %d\n", i);
i = kdk_conf2_get_int(setting, "int");
printf("Int value is %d\n", i);
success = kdk_conf2_set_int(setting, "int", i + 1);
if (0 == success)
{
printf("set int failed\n");
}
/**********长整形读写**********/
long l = kdk_conf2_get_default_int(setting, "long");
printf("Long default value is %d\n", l);
l = kdk_conf2_get_int(setting, "long");
printf("Long value is %d\n", l);
success = kdk_conf2_set_int(setting, "long", l + 1);
if (0 == success)
{
printf("set long failed\n");
}
/**********无符号整形读写**********/
unsigned int u = kdk_conf2_get_default_int(setting, "uint");
printf("Uint default value is %d\n", u);
u = kdk_conf2_get_int(setting, "uint");
printf("Uint value is %d\n", u);
success = kdk_conf2_set_int(setting, "uint", u + 1);
if (0 == success)
{
printf("set uint failed\n");
}
/**********无符号长整形读写**********/
unsigned long t = kdk_conf2_get_default_int(setting, "ulong");
printf("Ulong default value is %d\n", t);
t = kdk_conf2_get_int(setting, "ulong");
printf("Ulong value is %d\n", t);
success = kdk_conf2_set_int(setting, "ulong", t + 1);
if (0 == success)
{
printf("set ulong failed\n");
}
/**********布尔型读写**********/
int b = kdk_conf2_get_default_boolean(setting, "enable");
printf("Enable default value is %s\n", b ? "true" : "false");
b = kdk_conf2_get_boolean(setting, "enable");
printf("Enable value is %s\n", b ? "true" : "false");
success = kdk_conf2_set_boolean(setting, "enable", !b);
if (0 == success)
{
printf("set enable failed\n");
}
/**********浮点型读写**********/
double d = kdk_conf2_get_default_double(setting, "transparency");
printf("Transparency default value is %lf\n", d);
d = kdk_conf2_get_double(setting, "transparency");
printf("Transparency value is %lf\n", d);
success = kdk_conf2_set_double(setting, "transparency", d + 1);
if (0 == success)
{
printf("Set transparency failed\n");
}
/**********字符串读写**********/
char *s = kdk_conf2_get_default_string(setting, "name");
printf("Name default value is %s\n", s);
s = kdk_conf2_get_string(setting, "name");
printf("Name value is %s\n", s);
success = kdk_conf2_set_string(setting, "name", "dsefe");
if (0 == success)
{
printf("Set name failed\n");
}
/**********字符串列表读写**********/
char **sv = kdk_conf2_get_default_strv(setting, "list");
if (sv)
{
printf("List default value :\n");
for (int i = 0; sv[i]; i++)
{
printf("\t%s\n", sv[i]);
}
g_strfreev(sv);
}
sv = kdk_conf2_get_strv(setting, "list");
if (sv)
{
printf("List value :\n");
for (int i = 0; sv[i]; i++)
{
printf("\t%s\n", sv[i]);
}
g_strfreev(sv);
}
const char *v[] = {"CESI仿宋-GB13000", "CESI_FS_GB13000", NULL};
success = kdk_conf2_set_strv(setting, "list", v);
if (0 == success)
{
printf("Set list failed\n");
}
}
char *description = kdk_conf2_get_descrition(setting, "int");
if (description)
{
printf("Int description: %s\n", description);
free(description);
}
char *summary = kdk_conf2_get_summary(setting, "int");
if (summary)
{
printf("Int summary: %s\n", summary);
free(summary);
}
char *type = kdk_conf2_get_type(setting, "int");
if (type)
{
printf("Int type: %s\n", type);
free(type);
}
kdk_conf2_reset(setting, "int");
int writable = kdk_conf2_is_writable(setting, "int");
printf("Int is %s\n", writable ? "writable" : "not writable");
// kdk_conf2_connect_signal(setting, "reload", on_reload, NULL);
kdk_conf2_reload();
char **schemas = kdk_conf2_list_schemas("test", NULL);
if (schemas)
{
printf("test schemas:\n");
for (int i = 0; schemas[i]; i++)
{
printf("\t%s\n", schemas[i]);
free(schemas[i]);
}
free(schemas);
}
KSettings *externds_setting = kdk_conf2_new_extends_id("test.notice", "test.notice.tss", NULL);
if (externds_setting)
{
printf("kdk_conf2_new_extends_id successed\n");
}
int is_schema = kdk_conf2_is_schema("control-center.notice", NULL);
printf("control-center.notice is a %s shcema\n", is_schema ? "valid" : "invalid");
// 注销句柄
kdk_conf2_ksettings_destroy(setting);
return 0;
}
}

97
src/conf2/test/test.yaml Normal file
View File

@ -0,0 +1,97 @@
test:
3.20.1.31-0k2.11:
powermanager:
sleep:
_type: b
_default: 'true'
dormant:
_type: b
_default: 'true'
shutdown:
_type: b
_default: 'true'
_permission: final
switch-user:
_type: b
_default: 'true'
_permission: stable
enum_org.ukui.test.Type:
- _nick: none
_value: 0x00
- _nick: corner
_value: 0x01
- _nick: all
_value: 0x02
notice:
_summary: This is test schema
_description: This schema contains various basic types of keys
enable:
_type: b
_default: 'true'
_description: Whether an OSD notification is shown to notify about changes
_summary: Show OSD notification
int:
_type: i
_default: '8080'
_description: "The port on the machine defined by “/apt/proxy/host”\
\ that you\n proxy through."
_range: 0,65535
_summary: APT proxy port
long:
_type: x
_default: '8080'
_description: "The port on the machine defined by “/apt/proxy/host”\
\ that you\n proxy through."
_summary: APT proxy port
uint:
_type: u
_default: '8080'
_description: "The port on the machine defined by “/apt/proxy/host”\
\ that you\n proxy through."
_summary: APT proxy port
ulong:
_type: t
_default: '8080'
_description: "The port on the machine defined by “/apt/proxy/host”\
\ that you\n proxy through."
_summary: APT proxy port
name:
_type: s
_default: ''
_description: The name passed to the sidebar
_summary: app's name
type:
_type: enum
_default: corner
_description: the type of notice in system.
_range: '@enum_org.ukui.test.Type'
_summary: type of notice message
transparency:
_type: d
_default: '0.65'
_description: Control the transparency of all components
_summary: Control the transparency of all components
list:
_type: as
_default: '[''CESI仿宋-GB13000'',''CESI_FS_GB13000'', ''CESI仿宋-GB18030'']'
_description: Control panel _default font list
_summary: Control panel _default font list
proxy:
key:
_type: i
_default: 0
2.0.0.0-0k0.0:
powermanager:
_permission: final
sleep:
_type: b
_default: 'true'
dormant:
_type: b
_default: 'true'
shutdown:
_type: b
_default: 'true'
switch-user:
_type: b
_default: 'true'

View File

@ -1,3 +1,4 @@
#!/usr/bin/python3
#
# libkysdk-system's Library
#
@ -16,11 +17,10 @@
# You should have received a copy of the GNU General Public License
# along with this library. If not, see <https://www.gnu.org/licenses/>.
#
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
#
#
#!/usr/bin/python3
import configparser
import yaml
import sys, os
@ -31,24 +31,28 @@ def convert_one_file(file):
config.read(file)
# 将配置文件数据转换为字典
data = {'app':{'version':{'children':{}}}}
version = data['app']['version']['children']
data = {'app':{'2.0.0.0-0k0.0':{}}}
version = data['app']['2.0.0.0-0k0.0']
for section in config.sections():
version[section] = {}
for option in config.options(section):
value = config.get(section, option)
if 'keys' not in version[section]:
version[section]['keys'] = {}
version[section]['keys'][option] = {}
version[section]['keys'][option]["default"] = value
version[section]['keys'][option]["_type"] = 's'
value = value.strip()
value = value.strip("'")
value = value.strip('"')
version[section][option] = {}
version[section][option]["_default"] = value
version[section][option]["_type"] = 's'
if not os.path.exists('yaml'):
os.makedirs('yaml')
# 将字典转换为YAML格式并写入文件
with open(f'/home/kylin/yaml/{file.rsplit("/",maxsplit=1)[1].rsplit(".", maxsplit = 1)[0]}.yaml', 'w') as yaml_file:
home = os.getenv('HOME')
with open(f'{home}/yaml/{file.rsplit("/",maxsplit=1)[1].rsplit(".", maxsplit = 1)[0]}.yaml', 'w') as yaml_file:
yaml.dump(data, yaml_file, allow_unicode = True)
# 参数传入.conf或.ini结尾的ini格式配置文件或目录路径
# 将传入的所有配置文件或目录下的所有配置文件转换为yaml格式生成在~/yaml路径下
if __name__ == "__main__":
args = sys.argv[1:]
for arg in args:
@ -61,4 +65,4 @@ if __name__ == "__main__":
if arg.endswith('.conf') or arg.endswith('.ini'):
convert_one_file(arg)
else:
print(f'argument{arg} is not a conf file')
print(f'argument{arg} is not a conf file')

View File

@ -1,3 +1,4 @@
#!/usr/bin/python3
#
# libkysdk-system's Library
#
@ -16,132 +17,115 @@
# You should have received a copy of the GNU General Public License
# along with this library. If not, see <https://www.gnu.org/licenses/>.
#
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
#
#
#!/usr/bin/python3
import os
import re
import sys
import xml.etree.ElementTree as ET
import yaml
import ast
import sys, os, re
def convert_one_file(file):
def convert_one_file(data:dict, path:str, file:str):
global organization
# 解析XML文件到树中
tree = ET.parse(file)
root = tree.getroot()
# 将XML数据转换为Python字典
data = {}
#处理枚举
for enum in root.findall('.//enum'):
list = []
id = enum.attrib.get('id')
for value in enum:
item = {}
item['nick'] = value.get('nick')
item['value'] = value.get('value')
list.append(item)
data[f'enum_{id}'] = list
#处理schema下的key schema不管
schema_list = root.findall('.//schema')
for schema in schema_list:
schema_map = {}
keys = {}
for key in schema.findall('.//key'):
item = {}
key_name = key.attrib.get('name')
key_type = key.attrib.get('type')
#type 不存在 就是枚举类型
if key_type is None:
enumid = key.attrib.get('enum')
item['range'] = f'@enum_{enumid}'
item['_type'] = 'enum'
for child in key:
tag = child.tag
item[tag] = child.text.strip('\'')
else:
item['_type'] = key_type
for child in key:
text = ""
tag = child.tag
text = child.text
if text is None:
text = ''
text = text.strip() #去掉前后空白否则可能影响ast.literal_eval解析字符串
text = text.strip('\'') #部分xml空字符串默认值会写''
text = text.strip('\"') #部分xml空字符串默认值会写''
text = text.replace('\t','') #删除原xml中使下一行缩进而使用的制表符
if tag == 'range':
item['range'] = f'{child.attrib.get("min")},{child.attrib.get("max")}'
# if tag == 'default':
# if key_type[0] in 'isbdtou':
# item['default'] = text
# else:
# parser_data = ast.literal_eval(text.strip())
# item['default'] = parser_data
else:
item[tag] = text
keys[key_name] = item
if keys:
schema_map['keys'] = keys
data[schema.attrib.get('id').rsplit('.', maxsplit = 1)[1]] = schema_map
return data
if os.path.exists(f'{path}/{file}'):
tree = ET.parse(f'{path}/{file}')
root = tree.getroot()
#处理枚举
for enum in root.findall('.//enum'):
list = []
id = enum.attrib.get('id')
group_list = id[len(organization) + 1:].split('.')
if group_list[0] not in data:
data[group_list[0]] = {version:{}}
tmp = data[group_list[0]][version]
for value in enum:
item = {}
item['_nick'] = value.get('nick')
item['_value'] = value.get('value')
list.append(item)
tmp[f'enum_{id}'] = list
#处理schema下的key schema不管
schema_list = root.findall('.//schema')
for schema in schema_list:
id = schema.attrib.get('id')
group_list = id[len(organization) + 1:].split('.')
if group_list[0] not in data:
data[group_list[0]] = {version:{}}
tmp = data[group_list[0]][version]
for group in group_list[1:]:
if group not in tmp:
tmp[group] = {}
tmp = tmp[group]
for key in schema.findall('.//key'):
item = {}
key_name = key.attrib.get('name')
key_type = key.attrib.get('type')
#type 不存在 就是枚举类型
if key_type is None:
enumid = key.attrib.get('enum')
item['_range'] = f'@enum_{enumid}'
item['_type'] = 'enum'
else:
item['_type'] = key_type
for child in key:
tag = child.tag
text = '' if child.text is None else child.text
text = text.strip()
text = text.strip('\'') #部分xml空字符串默认值会写''
text = text.strip('\"') #部分xml空字符串默认值会写""
text = text.replace('\n\t','') #删除原xml中使下一行缩进而使用的制表符
if tag == 'range':
text = f'{child.attrib.get("min")},{child.attrib.get("max")}'
item[f'_{tag}'] = text
tmp[key_name] = item
else:
print(f'{path}/{file} not exists')
# 转换单个app的所有配置文件并生成到一个yaml文件中
if __name__ == '__main__':
app_name = sys.argv[1]
app = sys.argv[1]
version = '2.0.0-0k0.0'
if 3 == len(sys.argv):
version = sys.argv[2]
# 读取app的所有配置文件
app_config_files = {}
file_list = []
for root, dirs, files in os.walk("/usr/share/glib-2.0/schemas"):
if f'{app_name}.gschema.xml' in files:
app_config_files[app_name] = convert_one_file(os.path.join(root, f'{app_name}.gschema.xml'))
for file in files:
if re.match(app_name + r'\..*' + '.gschema.xml' + r'$', file):
file_path = os.path.join(root, file)
app_config_files[file_path[28:-12]] = convert_one_file(file_path)
file_list.append(file_path[28:-12])
# 将配置合并
# 按照每个元素分割后的字符串个数对列表进行降序排序
file_list = sorted(file_list, key=lambda x: len(x.split('.')), reverse= True)
# if app_name in file_list:
# file_list.remove(app_name)
parent = ''
child = ''
for key in file_list:
if key == app_name:
break
list = key.rsplit('.',maxsplit=1)
parent = list[0]
child = list[1]
# 将本文件的字典 添加到父文件的 'children'组中
if parent in app_config_files:
if 'children' not in app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]:
app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]['children'] = {}
app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]['children'].update(app_config_files[key])
else:
tmp_map = {parent.rsplit('.',maxsplit = 1)[1]:{'children':{}}}
tmp_map[parent.rsplit('.',maxsplit = 1)[1]]['children'].update(app_config_files[key])
key = parent
app_config_files[parent] = tmp_map
file_list.append(parent)
# 添加假的版本号 生成后需要手改为包的正确版本
data = {}
data[app_name.rsplit('.',1)[1]] = {}
data[app_name.rsplit('.',1)[1]][version] = app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]]
path = '/usr/share/glib-2.0/schemas'
if 'keys' in app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]].keys():
data[app_name.rsplit('.',1)[1]][version]['keys'] = app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]]['keys']
if len(sys.argv) > 3:
path = sys.argv[3]
organization = app.rsplit('.', 1)[0]
result = {}
# 读取app的所有配置文件
file_list = []
pattren = re.compile(r'^{}.*\.gschema\.xml$'.format(re.escape(app)))
for root, dirs, files in os.walk(path):
for file in files:
if pattren.match(file):
file_list.append(file)
# 按照每个元素分割后的字符串个数对列表进行降序排序
file_list = sorted(file_list, key=lambda x: len(x.split('.')), reverse=False)
for file in file_list:
convert_one_file(result, path, file)
# 生成yaml文件
yaml_data = yaml.safe_dump(data,allow_unicode = True)
# 生成yaml文件
yaml_data = yaml.safe_dump(result, allow_unicode = True)
# 将YAML数据写入文件
file = f"/home/kylin/yaml/{app_name}.yaml"
if not os.path.exists('/home/kylin/yaml'):
os.makedirs('/home/kylin/yaml')
home = os.getenv('HOME')
file = f"{home}/yaml/{app}.yaml"
if not os.path.exists(os.path.dirname(file)):
os.makedirs(os.path.dirname(file), exist_ok=True)
with open(file, 'w') as yaml_file:
yaml_file.write(yaml_data)

View File

@ -0,0 +1,74 @@
#!/usr/bin/python3
#
# libkysdk-system's Library
#
# Copyright (C) 2023, KylinSoft Co., Ltd.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this library. If not, see <https://www.gnu.org/licenses/>.
#
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
#
#
import yaml, json
import sys, os
def retrofit_the_structure(src:dict, dest:dict):
if not isinstance(src, dict):
# dest.update({'value':str(src)})
print(f"{src}'s root node not a dict")
return
for key, value in src.items():
if isinstance(value, dict):
dest[key] = {}
retrofit_the_structure(src[key], dest[key])
else:
dest[key] = {}
if isinstance(value, list):
dest[key]['_type'] = 'as'
dest[key]['_default'] = str(src[key])
else:
dest[key]['_type'] = 's'
dest[key]['_default'] = src[key]
def convert_one_file(src:str):
with open(src, 'r') as file:
data = json.loads(file.read())
base_name = os.path.basename(src)
name = os.path.splitext(base_name)[0]
result = {name : {'2.0.0.0-0k0.0': {}}}
retrofit_the_structure(data, result[name]['2.0.0.0-0k0.0'])
home = os.getenv('HOME')
if not os.path.exists(f'{home}/yaml'):
os.mkdir(f'{home}/yaml')
with open(f'{home}/yaml/{base_name[:-5]}.yaml', 'w') as yaml_file:
yaml_file.write(yaml.safe_dump(result, allow_unicode = True))
# 参数传入.json结尾的json格式配置文件或目录路径
# 将传入的所有配置文件或目录下的所有配置文件转换为yaml格式生成在~/yaml路径下
if __name__ == '__main__':
args = sys.argv[1:]
for arg in args:
if os.path.isdir(arg):
for root, dirs, files in os.walk(arg):
for file in files:
if file.endswith('.json'):
convert_one_file(f'{root}/{file}')
else:
if arg.endswith('.json'):
convert_one_file(arg)
else:
print(f'argument{arg} is not a json file')

View File

@ -22,19 +22,21 @@
#include "../api/ksettingsschema.h"
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkScrolledWindow *left_scrolled_window = NULL;
static GtkScrolledWindow *right_scrolled_window = NULL;
//左侧配置树
// 左侧配置树
static GtkTreeView *tree_folders = NULL;
//左侧树选中节点对应的键值表
// 左侧树选中节点对应的键值表
static GtkTreeView *table_configure = NULL;
//tree_folders节点路径: 路径组成的schema id的配置数据
// tree_folders节点路径: 路径组成的schema id的配置数据
static GHashTable *configure_models = NULL;
enum ConfigureAttr
@ -72,7 +74,7 @@ void on_entry_button_clicked(GtkButton *button, gpointer user_data)
int is_compliance = 0;
const gchar *endptr = NULL;
GError *error = NULL;
char *type = g_hash_table_lookup(schema_key, "data_type");
char *type = g_hash_table_lookup(schema_key, "value_type");
if (0 != strcmp(type, "enum"))
{
GVariant *variant = g_variant_parse(G_VARIANT_TYPE(type), text, NULL, &endptr, &error);
@ -145,7 +147,20 @@ void on_entry_button_clicked(GtkButton *button, gpointer user_data)
goto out;
}
GVariant *variant = g_variant_new("(sssss)", getlogin(), schema->id, schema->version, list[1], text);
uid_t uid = getuid(); // 获取当前进程的用户ID
char user_name[128] = {0};
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
if (NULL == pw)
{
strcpy(user_name, "root");
}
else
{
strcpy(user_name, pw->pw_name);
endpwent();
}
GVariant *variant = g_variant_new("(sssss)", user_name, schema->id, schema->version, list[1], text);
result = g_dbus_proxy_call_sync(proxy,
"set",
variant,
@ -155,6 +170,7 @@ void on_entry_button_clicked(GtkButton *button, gpointer user_data)
&error);
if (error != NULL)
{
printf("%s", error->message);
g_error_free(error);
goto out;
}
@ -171,7 +187,7 @@ out:
g_object_unref(connection);
if (response)
{
g_hash_table_replace(schema_key, "user_value", text);
g_hash_table_replace(schema_key, "custom_value", text);
GtkTreeIter iter;
GtkListStore *store = gtk_tree_view_get_model(table_configure);
@ -185,9 +201,9 @@ out:
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
COLUMN_NAME, g_hash_table_lookup(value, "property"),
COLUMN_TYPE, g_hash_table_lookup(value, "data_type"),
COLUMN_VALUE, g_hash_table_lookup(value, "user_value") ? g_hash_table_lookup(value, "user_value") : g_hash_table_lookup(value, "default_value"),
COLUMN_NAME, g_hash_table_lookup(value, "node_name"),
COLUMN_TYPE, g_hash_table_lookup(value, "value_type"),
COLUMN_VALUE, g_hash_table_lookup(value, "custom_value") ? g_hash_table_lookup(value, "custom_value") : g_hash_table_lookup(value, "default_value"),
COLUMN_SUMMARY, g_hash_table_lookup(value, "summary"),
-1);
}
@ -250,7 +266,7 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
GtkWidget *vbox = gtk_vbox_new(FALSE, 15);
sprintf(tmp, "%s%s", title_array[0], g_hash_table_lookup(schema_key, "property"));
sprintf(tmp, "%s%s", title_array[0], g_hash_table_lookup(schema_key, "node_name"));
GtkWidget *name_label = gtk_label_new(tmp);
gtk_widget_set_halign(name_label, GTK_ALIGN_START);
gtk_box_pack_start(vbox, name_label, TRUE, TRUE, 0);
@ -271,13 +287,13 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
gtk_widget_set_halign(description_label, GTK_ALIGN_START);
gtk_box_pack_start(vbox, description_label, TRUE, TRUE, 0);
sprintf(tmp, "%s%s", title_array[4], g_hash_table_lookup(schema_key, "data_type"));
sprintf(tmp, "%s%s", title_array[4], g_hash_table_lookup(schema_key, "value_type"));
GtkWidget *type_label = gtk_label_new(tmp);
gtk_widget_set_halign(type_label, GTK_ALIGN_START);
gtk_box_pack_start(vbox, type_label, TRUE, TRUE, 0);
char *range = g_hash_table_lookup(schema_key, "range");
if ((NULL != range) && (0 != strcmp("enum", g_hash_table_lookup(schema_key, "data_type"))))
if ((NULL != range) && (0 != strcmp("enum", g_hash_table_lookup(schema_key, "value_type"))))
{
char **list = g_strsplit(range, ",", -1);
sprintf(tmp, "%s%s", title_array[5], list[0]);
@ -299,7 +315,7 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
gtk_widget_set_halign(default_label, GTK_ALIGN_START);
gtk_box_pack_start(vbox, default_label, TRUE, TRUE, 0);
sprintf(tmp, "%s%s", title_array[8], g_hash_table_lookup(schema_key, "user_value") ? g_hash_table_lookup(schema_key, "user_value") : "默认值");
sprintf(tmp, "%s%s", title_array[8], g_hash_table_lookup(schema_key, "custom_value") ? g_hash_table_lookup(schema_key, "custom_value") : "默认值");
GtkWidget *value_label = gtk_label_new(tmp);
gtk_label_set_line_wrap_mode(GTK_LABEL(value_label), GTK_WRAP_WORD);
// gtk_label_set_line_wrap(GTK_LABEL(value_label), TRUE);
@ -314,7 +330,7 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
GtkWidget *entry_button = gtk_button_new_with_label("设置自定义值");
gtk_widget_set_halign(entry_button, GTK_ALIGN_START);
// name 用来传参。。。。。。
sprintf(tmp, "%s|%s", gtk_tree_path_to_string(path), g_hash_table_lookup(schema_key, "property"));
sprintf(tmp, "%s|%s", gtk_tree_path_to_string(path), g_hash_table_lookup(schema_key, "node_name"));
gtk_widget_set_name(entry_button, tmp);
gtk_box_pack_start(entry_vbox, entry_button, TRUE, TRUE, 0);
@ -323,9 +339,9 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD);
gtk_box_pack_start(vbox, text_view, TRUE, TRUE, 0);
char *user_value = g_hash_table_lookup(schema_key, "user_value") ? g_hash_table_lookup(schema_key, "user_value") : g_hash_table_lookup(schema_key, "default_value");
char *custom_value = g_hash_table_lookup(schema_key, "custom_value") ? g_hash_table_lookup(schema_key, "custom_value") : g_hash_table_lookup(schema_key, "default_value");
GtkWidget *buffer = gtk_text_buffer_new(NULL);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buffer), user_value, strlen(user_value));
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buffer), custom_value, strlen(custom_value));
gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_view), GTK_TEXT_BUFFER(buffer));
if ((NULL != writable) && (0 != strcmp(writable, "public")))
@ -367,24 +383,27 @@ static void on_selection_changed(GtkTreeSelection *selection, gpointer data)
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
KSettingsSchema *schema = g_hash_table_lookup(configure_models, gtk_tree_path_to_string(path));
char *select_path = gtk_tree_path_to_string(path);
char node_path[2048];
char node_path[2048], tmp_path[64];
memset(node_path, 0, 2048);
char *tmp_path = gtk_tree_path_to_string(path);
GValue node_name = G_VALUE_INIT;
for (int i = 1; i <= strlen(tmp_path); i += 2)
memset(tmp_path, 0, 64);
char **nodes = g_strsplit(select_path, ":", -1);
for (int i = 0; nodes[i]; i++)
{
char tmp[1024];
memset(tmp, 0, 1024);
strncpy(tmp, tmp_path, i);
gtk_tree_model_get_iter_from_string(model, &iter, tmp);
GValue node_name = G_VALUE_INIT;
strcat(tmp_path, nodes[i]);
gtk_tree_model_get_iter_from_string(model, &iter, tmp_path);
gtk_tree_model_get_value(model, &iter, 0, &node_name);
if (0 < strlen(node_path))
sprintf(node_path, "%s/%s", node_path, g_value_get_string(&node_name));
else
strcpy(node_path, g_value_get_string(&node_name));
g_value_unset(&node_name);
strcat(tmp_path, ":");
}
g_strfreev(nodes);
gtk_entry_set_text(GTK_ENTRY(data), node_path);
GtkListStore *store = gtk_tree_view_get_model(table_configure);
@ -401,9 +420,9 @@ static void on_selection_changed(GtkTreeSelection *selection, gpointer data)
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
COLUMN_NAME, g_hash_table_lookup(value, "property"),
COLUMN_TYPE, g_hash_table_lookup(value, "data_type"),
COLUMN_VALUE, g_hash_table_lookup(value, "user_value") ? g_hash_table_lookup(value, "user_value") : g_hash_table_lookup(value, "default_value"),
COLUMN_NAME, g_hash_table_lookup(value, "node_name"),
COLUMN_TYPE, g_hash_table_lookup(value, "value_type"),
COLUMN_VALUE, g_hash_table_lookup(value, "custom_value") ? g_hash_table_lookup(value, "custom_value") : g_hash_table_lookup(value, "default_value"),
COLUMN_SUMMARY, g_hash_table_lookup(value, "summary"),
-1);
}
@ -454,7 +473,7 @@ static void _find_search_node(char **list, GtkTreePath **path, GtkTreeModel *mod
static void on_search_entry_activated(GtkWidget *entry, gpointer user_data)
{
const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
if(g_str_equal("", text))
if (g_str_equal("", text))
return;
char **list = g_strsplit(text, "/", -1);
@ -484,23 +503,27 @@ static void on_search_entry_activated(GtkWidget *entry, gpointer user_data)
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
char node_path[2048];
char *select_path = gtk_tree_path_to_string(path);
char node_path[2048], tmp_path[64];
memset(node_path, 0, 2048);
char *tmp_path = gtk_tree_path_to_string(path);
GValue node_name = G_VALUE_INIT;
for (int i = 1; i <= strlen(tmp_path); i += 2)
memset(tmp_path, 0, 64);
char **nodes = g_strsplit(select_path, ":", -1);
for (int i = 0; nodes[i]; i++)
{
char tmp[1024];
memset(tmp, 0, 1024);
strncpy(tmp, tmp_path, i);
gtk_tree_model_get_iter_from_string(model, &iter, tmp);
GValue node_name = G_VALUE_INIT;
strcat(tmp_path, nodes[i]);
gtk_tree_model_get_iter_from_string(model, &iter, tmp_path);
gtk_tree_model_get_value(model, &iter, 0, &node_name);
if (0 < strlen(node_path))
sprintf(node_path, "%s/%s", node_path, g_value_get_string(&node_name));
else
strcpy(node_path, g_value_get_string(&node_name));
g_value_unset(&node_name);
strcat(tmp_path, ":");
}
g_strfreev(nodes);
gtk_entry_set_text(GTK_ENTRY(entry), node_path);
}
g_strfreev(list);
@ -509,6 +532,7 @@ static void on_search_entry_activated(GtkWidget *entry, gpointer user_data)
g_strfreev(list);
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_folders);
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tree_folders), path);
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tree_folders), path, NULL, FALSE, 0.0, 0.0);
gtk_tree_selection_select_path(selection, path);
gtk_widget_queue_draw(tree_folders);
@ -526,10 +550,10 @@ static void on_folder_selected(GtkFileChooser *chooser, gint response_id, gpoint
if (0 == success)
{
GtkWidget *dialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"保存配置数据到文件失败");
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"保存配置数据到文件失败");
// 运行消息框
gtk_dialog_run(GTK_DIALOG(dialog));
@ -538,7 +562,7 @@ static void on_folder_selected(GtkFileChooser *chooser, gint response_id, gpoint
gtk_widget_destroy(dialog);
}
}
break;
break;
default:
break;
}
@ -573,12 +597,12 @@ static gboolean entry_match_func(GtkEntryCompletion *completion, const char *key
gtk_tree_model_get(model, iter, 0, &value, -1);
char *p = value, *q = p;
for(; *p != '\0'; p++)
for (; *p != '\0'; p++)
{
if(*p == '/')
if (*p == '/')
q = p;
}
if(strstr(q, key))
if (strstr(q, key))
return TRUE;
else
return FALSE;
@ -644,6 +668,8 @@ static void draw_scrolled_window(GtkTreeStore *store_app, GtkTreeStore *store_co
{
if (NULL == schemas_table)
kdk_conf2_schema_update_schemas_table();
if (NULL == schemas_table)
exit(0);
GtkTreeIter iter;
@ -687,7 +713,7 @@ int main(int argc, char *argv[])
gtk_init(&argc, &argv);
// 创建窗口
// 创建窗口
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// gtk_window_set_title(GTK_WINDOW(window), "conf2-editor");
gtk_window_set_default_size(GTK_WINDOW(window), 1024, 768);
@ -700,7 +726,6 @@ int main(int argc, char *argv[])
gtk_widget_set_size_request(search_entry, -1, 10);
gtk_box_pack_start(GTK_BOX(box), search_entry, FALSE, FALSE, 0);
g_signal_connect(search_entry, "activate", G_CALLBACK(on_search_entry_activated), NULL);
GtkWidget *completion = gtk_entry_completion_new();
gtk_entry_completion_set_text_column(GTK_ENTRY_COMPLETION(completion), 0);

376
src/conf2/tools/kconf2-editor.py Executable file
View File

@ -0,0 +1,376 @@
#!/usr/bin/python3
import os
import sys
import yaml
import logging
sys.path.append('/home/kylin/disk/kylinos-src/libkysdk-base/src/conf2/service')
import conf2Utils
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as msgbox
import tkinter.filedialog as filedialog
import dbus
from gi.repository import GLib
target_view = {}
def on_tree_right_click(event):
global right_select_item
item = tree.identify_row(event.y)
if item and tree.parent(item) == "":
right_select_item = item
download_menu.post(event.x_root, event.y_root)
def close_menu(event):
download_menu.unpost()
def on_search():
pack_list = root.pack_slaves()
if view_frame in pack_list:
view_frame.pack_forget()
search_frame.pack(side='bottom', fill='both', expand=True)
search_tree.delete(*search_tree.get_children())
search_entry.config(state='normal')
# search_entry.event_generate("<KeyRelease>")
else:
search_frame.pack_forget()
view_frame.pack(side='bottom', fill='both', expand=True)
items = tree.selection()
if items:
text = tree.item(items[0], 'tags')[0]
search_entry.delete(0, 'end')
search_entry.insert(0, text)
else:
search_entry.delete(0, 'end')
search_entry.config(state='readonly')
def on_search_entry_change(event):
new_text = event.widget.get()
search_tree.delete(*search_tree.get_children())
if new_text == '':
return
for key in search_list.keys():
name_list = key.split('/')
if new_text in name_list[-1] or key.startswith(new_text):
search_tree.insert('', 'end', text= key)
def on_download():
global target_view
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
if path:
success = converter.editor_save(target_view, path)
if success:
msgbox.showinfo(message='Save successed')
else:
msgbox.showinfo(message='Save failed')
def on_download_one():
global target_view
key = tree.item(right_select_item, 'text')
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
if path:
success = converter.editor_save({key:target_view[key]}, path)
if success:
msgbox.showinfo(message='Save successed')
else:
msgbox.showinfo(message='Save failed')
def on_import_file():
pass
def on_set():
try:
if combobox.get() != 'custom':
msgbox.showinfo(message='Not custom veiw')
user = destination_file.split('/')[2]
key = id = value = ''
for widget in inner_frame.winfo_children():
if isinstance(widget, tk.Text):
if 'key' in widget.winfo_name:
key = widget.get()
if 'id' in widget.winfo_name:
id = widget.get()
if 'custom' in widget.winfo_name:
value = widget.get()
path = search_entry.get()
version = path.split('/')[1]
print(f'{user} {id} {version} {key} {value}')
bus = dbus.SystemBus()
obj = bus.get_object('com.kylin.kysdk.conf2', '/com/kylin/kysdk/conf2')
interface = dbus.Interface(obj, 'com.kylin.kysdk.conf2')
# success = interface.set(user, id, version, key, value)
# if success:
# global target_view
# target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
# msgbox.showinfo(message='Set successed')
# else:
# msgbox.showinfo(message='Set failed')
except Exception as e:
print(e)
def on_search_tree_select(event):
items = search_tree.selection()
text = search_tree.item(items[0], 'text')
tree.selection_set(search_list[text])
tree.see(search_list[text])
search_frame.pack_forget()
view_frame.pack(side='bottom', fill='both', expand=True)
def on_tree_select(event):
selected_item = tree.selection()
global target_view
if not selected_item:
return
item = selected_item[0]
tag = tree.item(item, 'tags')[0]
search_entry.config(state='normal')
search_entry.delete(0, 'end')
search_entry.insert(0, tag)
search_entry.config(state='readonly')
if tree.parent(item) == '':
return
group_list = tag.split('/')
tmp = target_view
for group in group_list:
tmp = tmp[group]
for widget in inner_frame.winfo_children():
widget.destroy()
text = tree.item(item, 'text')
name_label = tk.Label(inner_frame, text=f'名称', anchor='w')
name_label.pack(side='top', fill='x')
name_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='key')
name_text.insert('1.0', text)
name_text.config(state='disabled')
name_text.pack(side='top', fill='x', expand=True)
type = tmp['_type'] if '_type' in tmp else 'group'
if len(group_list) > 1:
group_list.pop(1)
if type != 'group':
group_list.pop(-1)
id_label = tk.Label(inner_frame, text=f'路径', anchor='w')
id_label.pack(side='top', fill='x')
id_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='id')
id_text.insert('1.0', '.'.join(group_list))
id_text.config(state='disabled')
id_text.pack(side='top', fill='x', expand=True)
type_label = tk.Label(inner_frame, text=f'类型', anchor='w')
type_label.pack(side='top', fill='x')
type_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='type')
type_text.insert('1.0', type)
type_text.config(state='disabled')
type_text.pack(side='top', fill='x', expand=True)
if tmp.get('_summary') is not None:
summary_label = tk.Label(inner_frame, text=f'摘要', anchor='w')
summary_label.pack(side='top', fill='x')
summary_text = tk.Text(inner_frame, height=3, width=100, wrap='word')
summary_text.insert('1.0', tmp.get('_summary'))
summary_text.config(state='disabled')
summary_text.pack(side='top', fill='x', expand=True)
if tmp.get('_description') is not None:
decription_label = tk.Label(inner_frame, text=f'描述', anchor='w')
decription_label.pack(side='top', fill='x')
decription_text = tk.Text(inner_frame, height=3, width=100, wrap='word')
decription_text.insert('1.0', tmp.get('_description'))
decription_text.config(state='disabled')
decription_text.pack(side='top', fill='x', expand=True)
permission = tmp.get('_permission', 'public')
permission_label = tk.Label(inner_frame, text=f'权限', anchor='w')
permission_label.pack(side='top', fill='x')
permission_text = tk.Text(inner_frame, height=1, width=100, wrap='word')
permission_text.insert('1.0', permission)
permission_text.config(state='disabled')
permission_text.pack(side='top', fill='x', expand=True)
if '_default' in tmp:
default_value = tmp['_default']
if isinstance(default_value, bool):
default_value = 'true' if tmp['_default'] else 'false'
default_label = tk.Label(inner_frame, text=f'默认值', anchor='w')
default_label.pack(side='top', fill='x')
default_text = tk.Text(inner_frame, height=5, width=100, wrap='word', name='default')
default_text.insert('1.0', tmp['_default'])
default_text.config(state='disabled')
default_text.pack(side='top', fill='x', expand=True)
custom_value = tmp.get('_value')
if custom_value is None or custom_value == default_value:
custom_value = '默认值'
custom_label = tk.Label(inner_frame, text=f'当前值', anchor='w')
custom_label.pack(side='top', fill='x')
custom_text = tk.Text(inner_frame, height=5, width=100, wrap='word', name='custom')
custom_text.insert('1.0', custom_value)
custom_text.config(state='disabled')
custom_text.pack(side='top', fill='x', expand=True)
if type != 'group' and permission == 'public' and combobox.get() == 'custom':
custom_text.config(state='normal')
set_button = tk.Button(inner_frame, text='Set', command=on_set)
set_button.pack(side='top')
def on_combobox_select(event):
selected_item = combobox.get()
global target_view
if selected_item == 'custom':
target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
else:
dirs = []
for dir in list(reversed(options)):
if dir == 'user':
dirs.append(f'{destination_file}/.config/kylin-config/configs')
else:
dirs.append(f'/etc/kylin-config/{dir}')
if dir == selected_item:
break
target_view = converter.load_dirs_config(dirs)
tree.delete(*tree.get_children())
for widget in inner_frame.winfo_children():
widget.destroy()
search_list.clear()
populate_tree(tree, '', target_view)
view_frame.update()
def populate_tree(tree, node, dictionary):
global search_list
tag = tree.item(node, 'tags')
for key, value in dictionary.items():
if isinstance(value, dict):
child_node = tree.insert(node, 'end', text=key)
if isinstance(tag, str):
tree.item(child_node, tags=(key))
else:
tree.item(child_node, tags=(f'{tag[0]}/{key}'))
search_list[f'{tag[0]}/{key}'] = child_node
populate_tree(tree, child_node, value)
root = tk.Tk()
root.title("kconf2-editor")
root.geometry('1024x768')
root.bind("<Button-1>", close_menu)
download_menu = tk.Menu(root, tearoff=0)
download_menu.add_command(label="下载", command=on_download_one)
download_menu.add_command(label="导入到其他目录", command=on_import_file)
search_list = {}
destination_file = os.getenv('HOME')
logger = logging.getLogger(f'{destination_file}/.log/widget.log')
converter = conf2Utils.Converter(logger)
# 读取统一视图
target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
# 创建一个Frame来包含按钮使其一直位于界面上方
button_frame = tk.Frame(root, height=10)
# 创建一个Frame来包含Treeview占满界面其他空余部分
view_frame = tk.Frame(root)
# 创建一个Frame来显示搜索结果它与view_frame只会显示一个
search_frame = tk.Frame(root)
# 排列root的三个子组件
button_frame.pack(side="top", fill="x")
view_frame.pack(side='top', fill='both', expand=True)
# 搜索栏
search_entry = tk.Entry(button_frame, state='readonly')
search_entry.bind("<KeyRelease>", on_search_entry_change)
# 搜索按钮
# search_icon = tk.BitmapImage(data=search_icon_data)
search_button = tk.Button(button_frame, text= 's', command=on_search, width=20)
# 下载按钮
# download_icon = tk.PhotoImage(file="download_icon.png")
download_button = tk.Button(button_frame, text= 'd', command=on_download, width=20)
# 视图选择列表
with open('/etc/kylin-config/conf2.yaml', 'r') as file:
configures = yaml.safe_load(file)
options = configures['dirs']
if os.path.exists(f'{destination_file}/.config/kylin-config/configs'):
options.append('user')
options.append('custom')
options.reverse()
combobox = ttk.Combobox(button_frame, values=options, width=20, state='readonly')
combobox.set(options[0])
combobox.bind("<<ComboboxSelected>>", on_combobox_select)
# 排列button_frame子组件
search_entry.pack(side="left", fill="both", expand= True)
combobox.pack(side='right')
download_button.pack(side="right", fill="x")
search_button.pack(side="right", fill="x")
# 创建Frame在view_frame的左侧显示配置树
left_frame = tk.Frame(view_frame)
left_frame.pack(side='left', fill='both')
# 创建Treeview显示配置树
tree = ttk.Treeview(left_frame)
tree.column('#0', width=200, stretch=True)
tree.heading('#0', text='SubFolders')
tree.bind("<<TreeviewSelect>>", on_tree_select)
tree.bind("<Button-3>", on_tree_right_click)
search_list.clear()
populate_tree(tree, '', target_view)
tree.pack(side='left', fill='both')
# 创建滚动条
tree_scrollbar = ttk.Scrollbar(left_frame, orient="vertical", command=tree.yview)
tree_scrollbar.pack(side="right", fill="y")
tree.configure(yscrollcommand=tree_scrollbar.set)
# 创建Frame在view_frame的右侧显示配置信息
right_frame = tk.Frame(view_frame)
right_frame.pack(side='right', fill='both', expand=True)
# 创建一个Canvas
canvas = tk.Canvas(right_frame)
canvas.pack(side="left", fill="both", expand=True)
# 将Canvas的窗口设置为Frame
inner_frame = tk.Frame(canvas)
inner_frame.grid(row=0, column=0, sticky="nsew")
canvas_window = canvas.create_window((0, 0), window=inner_frame, anchor="nw")
right_scrollbar = ttk.Scrollbar(right_frame, orient="vertical", command=canvas.yview)
right_scrollbar.pack(side="right", fill="y")
canvas.configure(yscrollcommand=right_scrollbar.set)
# 创建Treeview显示搜索匹配的路径
search_tree = ttk.Treeview(search_frame, show='tree')
search_tree.bind("<<TreeviewSelect>>", on_search_tree_select)
search_tree.pack(side='left', fill='both', expand=True)
search_scrollbar = ttk.Scrollbar(search_frame, orient="vertical", command=search_tree.yview)
search_scrollbar.pack(side="right", fill="y")
search_tree.configure(yscrollcommand=search_scrollbar.set)
root.mainloop()

View File

@ -23,13 +23,18 @@
#include <stdio.h>
void key_changed(KSettings *ksettigns, const char *key, void *user_data)
void on_key_changed(KSettings *ksettigns, const char *key, void *user_data)
{
char *value = kdk_conf2_get_value(ksettigns, key);
printf("%s changed to %s\n", key, value);
free(value);
}
void on_reload(KSettings *ksettigns, void *user_data)
{
printf("view reload\n");
}
/*句柄结构体内部元素*/
typedef struct _KSettingsPrivate
{
@ -62,6 +67,7 @@ static void print_help()
// " reset-recursively Reset all values in a given schema\n"
" writable Check if a key is writable\n"
" monitor Watch for changes\n"
// " monitor-reload Watch for realod\n"
" save Save User config in target folder"
"\n"
"Use kconf2 help \"COMMAND\" to get detailed help.\n");
@ -211,10 +217,21 @@ static void print_command(char *command)
" VERSION Specify the version of the schema\n"
" KEY Key in the schema\n");
}
// else if (0 == strcmp(command, "monitor-reload"))
// {
// printf("Usage:\n"
// " kconf2 monitor-reload\n"
// "\n"
// "Monitor reload to the view.\n"
// "Use ^C to stop monitoring.\n"
// "\n"
// "Args\n"
// " SCHEMA The name of the schema\n");
// }
else if (0 == strcmp(command, "list-schemas"))
{
printf("Usage:\n"
" kconf2 list-scemas [APP] [VERSION]\n"
" kconf2 list-scemas APP [VERSION]\n"
"\n"
"If you don't specify an app and version, list all installed schemas.\n"
"otherwise list schemas items that specify the app and version.\n"
@ -265,7 +282,10 @@ int main(int argc, char *argv[])
if (0 == strcmp(argv[1], "list-schemas"))
{
if (argc < 3)
print_help("list-schemas");
{
print_command("list-schemas");
exit(0);
}
gboolean limit_app = FALSE, limit_version = FALSE;
if (argc > 2)
limit_app = TRUE;
@ -296,13 +316,13 @@ int main(int argc, char *argv[])
g_hash_table_iter_init(&ver_iter, app_hash);
while (g_hash_table_iter_next(&ver_iter, &version, &version_hash))
{
if (limit_version && 0 != strcmp(argv[3], app->name))
if (limit_version && 0 != strcmp(argv[3], version->name))
continue;
printf("\t%s:\n", version->name);
GList *schemas = g_hash_table_get_keys(version_hash);
for (GList *tmp = schemas; tmp; tmp = tmp->next)
{
printf("\t\t%s\n", (char *)schemas->data);
printf("\t\t%s\n", (char *)tmp->data);
}
g_list_free(schemas);
}
@ -311,7 +331,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "list-children"))
{
if (argc < 3)
print_help("list-children");
{
print_command("list-children");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
{
@ -333,7 +356,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "list-keys"))
{
if (argc < 3)
print_help("list-keys");
{
print_command("list-keys");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -356,8 +382,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "list-recursively"))
{
if (argc < 3)
print_help("list-recursively");
{
print_command("list-recursively");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
{
@ -380,7 +408,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "get"))
{
if (argc < 4)
print_help("get");
{
print_command("get");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -400,7 +431,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "set"))
{
if (argc < 5)
print_help('set');
{
print_command("set");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -416,7 +450,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "range"))
{
if (argc < 4)
print_help('range');
{
print_command("range");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -438,15 +475,16 @@ int main(int argc, char *argv[])
{
if (0 == strcmp(type, "enum"))
{
char *endptr, *error;
char *endptr;
GError *error;
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
if (NULL == variant)
{
printf("parser enum error %s\n", error);
printf("parser enum error %s\n", error->message);
exit(0);
}
printf("enum\n");
printf("enum:\n");
char *nick = NULL;
gint32 value = 0;
@ -454,16 +492,14 @@ int main(int argc, char *argv[])
g_variant_get(variant, "a{si}", &iter);
while (g_variant_iter_loop(iter, "{si}", &nick, &value))
{
printf("'%s'\n", nick);
printf(" '%s'\n", nick);
}
g_variant_iter_free(iter);
g_variant_unref(variant);
}
else
{
printf("%s\n", range);
p = range;
printf("%x\n", ',');
while (*p != ',' && *p != '\0')
p++;
*p = '\0';
@ -476,16 +512,17 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "reset"))
{
if (argc < 4)
print_help('reset');
{
print_command("reset");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
{
printf("Wrong schema id\n");
exit(0);
}
if (NULL == kdk_conf2_schema_get_key(ksettings, argv[argc - 1]))
if (NULL == kdk_conf2_schema_get_key(ksettings->priv->schema, argv[argc - 1]))
{
printf("Wrong key\n");
exit(0);
@ -496,7 +533,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "monitor"))
{
if (argc < 3)
print_help('monitor');
{
print_command("monitor");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -509,10 +549,10 @@ int main(int argc, char *argv[])
if (4 == argc)
{
char *signal_name = g_strdup_printf("changed::%s", argv[3]);
id = kdk_conf2_connect_signal(ksettings, signal_name, key_changed, NULL);
id = kdk_conf2_connect_signal(ksettings, signal_name, on_key_changed, NULL);
}
else
id = kdk_conf2_connect_signal(ksettings, "changed", key_changed, NULL);
id = kdk_conf2_connect_signal(ksettings, "changed", on_key_changed, NULL);
if (id <= 0)
{
@ -523,10 +563,39 @@ int main(int argc, char *argv[])
for (;;)
g_main_context_iteration(NULL, TRUE);
}
else if (0 == strcmp(argv[1], "monitor-reload"))
{
if (argc < 2)
{
print_command("monitor-reload");
exit(0);
}
KSettings *ksettings = kdk_conf2_new("test.notice", NULL);
if (NULL == ksettings)
{
printf("Wrong schema id\n");
exit(0);
}
guint id = 0;
id = kdk_conf2_connect_signal(ksettings, "reload", on_reload, NULL);
if (id <= 0)
{
printf("Connect signal failed\n");
exit(0);
}
for (;;)
g_main_context_iteration(NULL, TRUE);
}
else if (0 == strcmp(argv[1], "writable"))
{
if (argc < 4)
print_help('writable');
{
print_command("writable");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -544,7 +613,10 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "describe"))
{
if (argc < 4)
print_help('describe');
{
print_command("describe");
exit(0);
}
KSettings *ksettings = kdk_conf2_new(id, version);
if (NULL == ksettings)
@ -558,10 +630,13 @@ int main(int argc, char *argv[])
else if (0 == strcmp(argv[1], "save"))
{
if (argc < 3)
print_help('save');
{
print_command("save");
exit(0);
}
int success = kdk_conf2_save_user_configure(argv[2]);
if(0 == success)
printf("save configure failed");
if (0 == success)
printf("save configure failed\n");
}
else
{

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
aux_source_directory(. SOURCESCODE)
add_library(kysdk-config SHARED ${SOURCESCODE})
set_target_properties(kysdk-config PROPERTIES VERSION 2.3.0 SOVERSION 2)
add_library(kyconf SHARED ${SOURCESCODE})
set_target_properties(kyconf PROPERTIES VERSION 2.5.0 SOVERSION 1)
add_executable(kyconf-test-struct test/test_structlist.c)
target_link_libraries(kyconf-test-struct kysdk-config)
target_link_libraries(kyconf-test-struct kyconf)
# GNU
include(GNUInstallDirs)
@ -18,7 +18,7 @@ else()
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
endif()
#
install(TARGETS kysdk-config
install(TARGETS kyconf
DESTINATION ${CMAKE_INSTALL_LIBDIR})
# install(TARGETS kyconf

20
src/config/Makefile Normal file
View File

@ -0,0 +1,20 @@
OBJ=gsettingsparse.o jsonparse.o structparse.o xmlparse.o
CFLAGS=-g -O0 -Wall -fPIC -I../ -I../utils/ -I../config/
CLIBS=-lpthread
CC:=$(shell bash -c 'type $(CC) &> /dev/null && echo $(CC) || echo gcc')
TARGET=libkyconf.so
LIBINST=libkyconf.so.1.0.0
LIBHEAD=kyconf.h
LIBINSTHEADER=/usr/include/kysdk/base/
all:$(OBJ)
$(CC) -o $(LIBINST) configure.c $(OBJ) $(CFLAGS) $(CLIBS) -shared
mkdir -p lib/
mv -f $(LIBINST) lib/
cd lib/ && ln -sf $(LIBINST) $(TARGET) && cd ..
-rm *.o &> /dev/null
clean:
-rm *.o &> /dev/null
-rm ../lib/$(TARGET) &> /dev/null

View File

@ -5,7 +5,7 @@ project(kydiagnostics LANGUAGES CXX)
set(DIAGNOSTICS_TOP_DIR ${CMAKE_CURRENT_LIST_DIR})
add_library(${PROJECT_NAME} SHARED)
set_target_properties(kydiagnostics PROPERTIES VERSION 2.3.0 SOVERSION 1)
set_target_properties(kydiagnostics PROPERTIES VERSION 2.5.0 SOVERSION 1)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -g)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)

View File

@ -36,4 +36,4 @@ int kdk_buried_point(char *appName , char *messageType , KBuriedPoint *data , in
}
return -1;
}
}

View File

@ -41,4 +41,4 @@ int main(void)
printf("buried point success !\n");
return 0;
}
}

View File

@ -6,12 +6,12 @@ include_directories(${GTK3_INCLUDE_DIRS})
link_directories(${GTK3_LIBRARY_DIRS})
add_definitions(${GTK3_CFLAGS_OTHER})
add_library(kysdk-gsetting SHARED ${SOURCESCODE})
set_target_properties(kysdk-gsetting PROPERTIES VERSION 2.3.0 SOVERSION 2)
add_library(kygsetting SHARED ${SOURCESCODE})
set_target_properties(kygsetting PROPERTIES VERSION 2.5.0 SOVERSION 1)
add_executable(test-kygsetting test/test-gsetting.c)
target_link_libraries(kysdk-gsetting ${GTK3_LIBRARIES})
target_link_libraries(test-kygsetting kysdk-gsetting)
target_link_libraries(kygsetting ${GTK3_LIBRARIES})
target_link_libraries(test-kygsetting kygsetting)
# install(TARGETS kygsetting
# DESTINATION lib/kysdk/kysdk-base)
@ -30,7 +30,7 @@ else()
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
endif()
#
install(TARGETS kysdk-gsetting
install(TARGETS kygsetting
DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES libkygsetting.h

View File

@ -4,19 +4,19 @@ include(FindPkgConfig)
pkg_check_modules(DBus REQUIRED
dbus-1)
include_directories(${DBus_INCLUDE_DIRS})
add_library(kysdk-log SHARED ${SOURCESCODE})
set_target_properties(kysdk-log PROPERTIES VERSION 2.3.0 SOVERSION 2)
add_library(kylog SHARED ${SOURCESCODE})
set_target_properties(kylog PROPERTIES VERSION 2.5.0 SOVERSION 1)
add_executable(kylog-testlog test/test-log.c)
add_executable(kylog-testsetdir test/test-setdir.c)
add_executable(kylog-testpressure test/test-pressure.c)
add_executable(kylog-testautowrap test/test-autowrap.c)
find_library(SYSTEMD_LIB systemd)
find_library(DBUS_LIB dbus-1)
target_link_libraries(kysdk-log kysdk-config pthread ${SYSTEMD_LIB} ${DBUS_LIB})
target_link_libraries(kylog-testlog kysdk-log)
target_link_libraries(kylog-testsetdir kysdk-log)
target_link_libraries(kylog-testautowrap kysdk-log)
target_link_libraries(kylog-testpressure kysdk-log)
target_link_libraries(kylog kyconf pthread ${SYSTEMD_LIB} ${DBUS_LIB})
target_link_libraries(kylog-testlog kylog)
target_link_libraries(kylog-testsetdir kylog)
target_link_libraries(kylog-testautowrap kylog)
target_link_libraries(kylog-testpressure kylog)
# install(TARGETS kylog
# DESTINATION lib/kysdk/kysdk-base)

20
src/log/Makefile Normal file
View File

@ -0,0 +1,20 @@
OBJ=core.o format.o klog_mqueue.o kylog.o write.o writeFile.o
CFLAGS=-g -O0 -Wall -fPIC -I../ -I../utils/ -I../config/
# CLIBS=-lpthread -lsystemd
CC:=$(shell bash -c 'type $(CC) &> /dev/null && echo $(CC) || echo gcc')
TARGET=libkylog.so
LIBINST=libkylog.so.1.0.0
LIBHEAD=kylog.h
LIBINSTHEADER=/usr/include/kylog/
all:$(OBJ)
$(CC) -o $(LIBINST) $(OBJ) $(CFLAGS) $(CLIBS) -shared
mkdir -p lib/
mv -f $(LIBINST) lib/
cd lib/ && ln -sf $(LIBINST) $(TARGET) && cd ..
-rm *.o &> /dev/null
clean:
-rm *.o &> /dev/null
-rm ../lib/$(TARGET) &> /dev/null

View File

@ -1,7 +1,7 @@
all:
gcc -o test-log test-log.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkysdk-log -lkysdk-config -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
gcc -o test-setdir test-setdir.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkysdk-log -lkysdk-config -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
gcc -o test-pressure test-pressure.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkysdk-log -lkysdk-config -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
gcc -o test-log test-log.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkylog -lkyconf -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
gcc -o test-setdir test-setdir.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkylog -lkyconf -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
gcc -o test-pressure test-pressure.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkylog -lkyconf -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
clean:
-rm test-log test-setdir test-pressure
-rm test-log test-setdir test-pressure

View File

@ -1,9 +1,9 @@
aux_source_directory(. SOURCESCODE)
add_library(kysdk-timer SHARED ${SOURCESCODE})
set_target_properties(kysdk-timer PROPERTIES VERSION 2.3.0 SOVERSION 2)
add_library(kytimer SHARED ${SOURCESCODE})
set_target_properties(kytimer PROPERTIES VERSION 2.5.0 SOVERSION 1)
add_executable(test-kytimer test/test-kytimer.c)
target_link_libraries(kysdk-timer pthread)
target_link_libraries(test-kytimer kysdk-timer)
target_link_libraries(kytimer pthread)
target_link_libraries(test-kytimer kytimer)
# install(TARGETS kytimer
# DESTINATION lib/kysdk/kysdk-base)
@ -22,7 +22,7 @@ else()
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
endif()
#
install(TARGETS kysdk-timer
install(TARGETS kytimer
DESTINATION ${CMAKE_INSTALL_LIBDIR})
# install(FILES libkytimer.h

26
src/timer/Makefile Normal file
View File

@ -0,0 +1,26 @@
CLIBS=-lpthread -lrt
CFLAGS=-g -O0 -Wall -fPIC -shared
CC=cc
TARGET=libkytimer.so
LIBINSTALLNAME=libkytimer.so.1.0.0
LIBINSTALLDIR=/usr/lib/
HEADERINSTALLDIR=/usr/include/
HEADERS=kytimer.h
.PHONY:all
.PHONY:clean
.PHONY:lib
all:lib
lib:
$(CC) $(CFLAGS) $(CLIBS) -o $(TARGET) libkytimer.c
mkdir -p lib/
mv $(TARGET) lib/$(LIBINSTALLNAME)
clean:
-rm ../lib/$(LIBINSTALLNAME)
target_install:TARGET
cp $(LIBINSTALLNAME) $(LIBINSTALLDIR)

View File

@ -1,5 +1,5 @@
all:
gcc -g -O0 -o test-kytimer test-kytimer.c -lkysdk-timer -lpthread
gcc -g -O0 -o test-kytimer test-kytimer.c -lkytimer -lpthread
clean:
rm demo
rm demo

View File

@ -1,6 +1,6 @@
aux_source_directory(. SOURCESCODE)
add_library(kyutils SHARED ${SOURCESCODE})
set_target_properties(kyutils PROPERTIES VERSION 2.3.0 SOVERSION 2)
set_target_properties(kyutils PROPERTIES VERSION 2.5.0 SOVERSION 1)
include_directories(.)
# install(TARGETS kyutils
# DESTINATION lib/kysdk/kysdk-base)

View File

@ -280,10 +280,11 @@ char *size_to_human_string(int options, uint64_t bytes, int base)
// if (frac % 10 == 0)
// frac /= 10; /* convert N.90 to N.9 */
sprintf(res, "%.2f", result);
frac = (frac / (1ULL << (exp - 10)) + 5) / 10;
double num = atof(res);
double ret = num - dec;
frac = ret * 100;
if (frac % 10 == 0)
sprintf(res, "%.f", result);
sprintf(res, "%.1f", result);
} else {
// frac = (frac / (1ULL << (exp - 10)) + 50) / 100;
// if (frac == 10)

View File

@ -54,4 +54,4 @@ int main()
printf("%.2f\n", result_numberical);
return 0;
}
}