#config-directory #bin #db #version #blob #client #meld

bin+lib meld-config-manager

用 Rust 编写的 meld 客户端

1 个不稳定版本

0.1.0 2022 年 5 月 29 日

#914文件系统

MIT 许可证

72KB
1.5K SLoC

Rust 1K SLoC // 0.1% comments Shell 565 SLoC // 0.1% comments

Gitlab pipeline status (self-hosted)

GitLab Release (custom instance)

Meld 文档

上游仓库

Meld 的规范和设计选择

目标

Meld 将实现跨系统配置控制的便捷性,以降低在多个系统上复制环境时的复杂性。


术语

  • Bin
    • 存储配置和数据库的目录
    • 每个 bin 应跟踪一组逻辑配置
      • 例如,用户的 DE 配置
  • 配置
    • 单个文件,直接提交或通过其父文件夹提交
    • 这些文件都按描述存储在 blobs/ 目录中
  • 子集
    • Bin 中配置的进一步细分
      • 在 DE bin 中,用户可以将他们的 "i3" 和 "polybar" 配置作为子集跟踪
      • 这很有帮助,因为这两个配置都是包含多个内部文件的文件夹
  • 家族
    • 子集的逻辑分组
      • 例如,"wm" 家族可能包含 "i3"、"polybar" 和 "dunst" 等子集
  • 映射路径
    • 系统上的映射文件夹
      • $HOME$/.config/i3/config - 存储
      • /home/icon/.config/i3/config - 解析的路径
    • 应该是解析正确所需的最小路径量
      • 这是为了避免有一堆变量
      • 由于配置在包设置后存储方式相似,因此 "prefix" 是唯一需要映射的部分
  • Blob
    • 跟踪的配置的名称,存储在 bin/blobs/NAME
    • Blob 名称是存储路径的 SHA512 哈希
    • Blob 版本按 bin/blobs/BLOB/n 跟踪
  • 映射
    • 为了正确跟踪目录的状态,我们对其进行 "快照" 处理
    • 这些快照以 <目录路径的 SHA512 哈希>-<快照版本> 命名
    • 映射文件包含在快照时刻目录中配置的 <BLOB>-<版本>

设计目标

  • 语言无关
    • 'meld' 是一种布局和协议
    • 使客户端实现变得容易
  • 大多数是可读文件
    • 没有奇怪或自定义的文件格式
  • 采用 "每个 bin 对应一个区域" 的哲学
    • 使类似配置的逻辑分组变得容易
    • 可以使用子集/家族进行进一步控制
    • 理想用途 - 一个 meld bin 用于您所有的 DE 配置
    • 非 DE 用途 - 一个 meld bin 用于您整个系统的配置
      • 虽然这可能会工作,但为什么要让它更复杂呢?
  • 以客户端无关或易于提供的方式构建
    • 应该能够在 SSH 或 HTTP 代理后面工作
    • 还应该能够直接在bin目录中操作
    • 使用不同客户端创建的bins应该能够互操作
  • 启用系统间的映射以获得最大灵活性
    • B1 - $HOME$:/home/icon
    • B2 - $HOME$:/home/drew.parker
    • 存储路径: $HOME$/.config/example.conf
  • 首先保持易用性和设计一致性
  • 通过使用git子系统启用基本版本控制(待办事项)

支持的操作和选项

  • init

    • 初始化一个新的bins
      • -p - 初始化所有必要的父目录
      • -f - 强制使用现有的目录
      • --comments - 向数据库中的"binfo"表添加有关bins的一些信息
        • 需要进一步调查;可能直接在bins根目录中的"info.txt"中存储(待办事项)
  • push

    • 将新的配置跟踪到bins中(或更新现有的配置)
    • -s/--subset - 添加子集信息
    • -t/--tag - 添加标签信息
    • -f/--family - 添加家族信息
  • pull

    • 从bins中安装配置
    • -t/--tag - 拉取匹配最新特定标签版本的配置
    • -v/--version - 拉取匹配指定版本的配置
    • -r/--recent - 如果-t/-v指定但未找到,则使用此选项拉取最新的配置
  • list

    • 列出bins中所有跟踪的配置
      • 此处添加一些显示选项(待办事项)
  • pivot

    • 在跟踪的表中重命名变量
    • 本质上是在数据库中重新定义变量
    • $HOME$ -> $HOME_ICON$
  • 同步上下

    • up - 将所有跟踪的配置的新版本拉入bins
      • 如果无法拉取新的配置则发出警告
    • down - 从bins中安装所有配置
      • 如果覆盖现有配置则发出警告/提示
    • 此处处理子集(待办事项)
  • 验证bins/configs/checksums

    • 确保目录包含所有必要的meld文件
    • 所有跟踪的配置都存在于系统上(基本上是同步dryrun?(待办事项))
    • 对所有blob文件进行散列,并确保其跟踪的散列匹配

Meld数据库和bins布局

meld.db文件是一个SQLite文件,包含2个表

  1. Configs - 将配置与blob名称匹配的主要表
    • id - 存储路径的SHA512哈希
    • subset - 一个可选字符串,用于标识配置是否是子集的成员
      • 如果没有在子集中,则为空
    • family - 一个可选字符串,用于标识配置是否是家族的成员
      • 如果没有在家族中,则为空
  2. Versions - 启用基本版本控制
    • id - blob内容的SHA512哈希
      • 如果版本指的是目录,则此为"DIR"
    • ver - 配置的当前版本(在推送先前跟踪的配置时递增)
    • tag - 用于标记特定版本的标签(例如,标记适用于旧软件版本的配置)
    • owner - 属于此版本条目的配置的ID(即blob名称)
  3. Maps - 启用目录状态的快照(仅在调用目录上的push时设置)
    • id - 目录路径的SHA512哈希
    • ver - 快照版本 - 仅当内部文件之一被更新时才递增
    • nhash - 所有配置内容的连接散列的散列(即hash(hash1 + hash2 + hash3))

Meld目录布局如下

meld_dir/
|  config.yml             # config and metadata about the bin (not currently implimented)
|  meld.db                # sqlite db file
|__blobs/
   |__<HASH1>/            # a config with 2 tracked versions
       |  1
       |  2
   |__<HASH2>/            # a config with 1 tracked config, and a blob config
       |  config.yml      # optional config; sets options like pruning (not currently implimented)
       |  1               
|__maps/
   |__<HASH2>-<Version>   # a map file for snapshoting the contents of a dir

示例Meld使用和树调试是通过设置RUST_LOG启用的

> RUST_LOG=debug meld /tmp/meld_test init
[2022-05-29T02:25:46Z INFO  libmeld::bin] Creating bin at /tmp/meld_test
[2022-05-29T02:25:46Z INFO  libmeld::bin] Creating "/tmp/meld_test"
[2022-05-29T02:25:46Z INFO  libmeld::bin] Creating "/tmp/meld_test/maps"
[2022-05-29T02:25:46Z INFO  libmeld::bin] Creating "/tmp/meld_test/blobs"
[2022-05-29T02:25:46Z INFO  libmeld::db] Creating "/tmp/meld_test/meld.db"
[2022-05-29T02:25:46Z INFO  meld] No Errors
> meld /tmp/meld_test push Cargo.toml
> echo "NONSENSE" > Cargo.toml
> meld /tmp/meld_test push Cargo.toml
> rm Cargo.toml
> meld /tmp/meld_test pull ~/Projects/meld/meld-rust/Cargo.toml -v 1
> head Cargo.toml
[package]
name = "meld"
version = "0.1.0"
edition = "2021"
description = "a meld client written in Rust"
authors = ["drew <[email protected]>"]
readme = "README.md"
license = "MIT"

[lib]
> meld /tmp/meld_test push src/
> tree /tmp/meld_test
/tmp/meld_test
├── blobs
│   ├── 18990ecaf4a799b7119dfef47a51eec51a6ba2c7c376527460d82cae2ec1ceeb23ab037904349405cd24c380aa80bcf737035cd22ff0dada53e7eed30dde4b9f
│   │   └── 1
│   ├── 1c54ad4c8d8eb4aeb8a85ac17b2505a1fab357ebbb53837ef753ea202e716470a43749c0e8aa25c8ec519d75677b593e3173a356cd0497aff691ec36b74a533c
│   ├── 355e95d5dbcbe1fba3e41ef3fcb60aa071028359269213a1e3bf034abbcf634c6ec8a10f12c602788cb38292729cd207309f8ba98ff9bbe9fc19795b186990a1
│   │   ├── 1
│   │   └── 2
│   ├── 396814739440b6c50dbd6df3844f6a0296e5d4656dc41c923a45365ba4dbdca050ad0e482075aebc5a587763fc02272dd6112de2ca6332f952d54fbe9a5b5e6f
│   │   └── 1
│   ├── 3befc5987409a51244955c15972cce01651df9f092a589211899bbf2a2d5b8b680b67bdd9d86af5099abf7b782fb0bfa33f009dd7baa99585d609e562733f1ec
│   │   └── 1
│   ├── 40dcd0373e6ee3e5987e0df6a6d449078edb858ca7d983d6dd5b0fc520f8748c8156e0f4231b5b90b31dfe4b2887ff35ca6587f7d413b2a0e2ae5841e2c42e6b
│   │   └── 1
│   ├── 5afe942f5ddb73f436c005a377163e1b1675812a77eae2942f0e0bf69b7ff13ede869e3e61240e2e776167745c7ace07545e8969d88b571a5fef192dc0421c6c
│   │   └── 1
│   ├── 6f8390c0bc657f16393eeee71327e6dce63d36136160b7e134cda47af0404ab0af84dbe86623872bda701bb924f05d928eaafe74f054a6bc0cd6211dd596077b
│   │   └── 1
│   ├── 7d71b39efc830dd5a6b750a04da9e2eb70a643a1d258dc6597506bd8e179879edb3f6750daeeadca0b0d297771fda17e612f610355c63a60d5c0c87ff39e684d
│   ├── 86aa385dc723c2b2a35e5cba823337be01599326345091b71b3f86283bd7a5a5303b50b5c382f6b3fb4a4b41307a7b0a653bdf0bfb2f9f59b30be916d0dd55ad
│   │   └── 1
│   ├── 92cdce5675765e1606b71f7603170dee57a26adda822a5cd6b86d059f4d0481e83a67130fb00289612b3220ee563fc3b6dcfbeab645bf578744527c77502e3d4
│   │   └── 1
│   ├── b04d9ac3de1e4e2d3a633832cc71955dcf696039d11a6750e34df8ad2e863afd158b77f9fc0ea589dff1daad5dd9d6df1946e9449ce43f9a38a4bf5c75b83f91
│   │   └── 1
│   ├── c3373f98aac47c4332ab89e27a3dbf1af844109b31a16eb0ed2f4b39df924dcb1c31df737f257eb162b68f7b9ac60ac2d5f620e83451bfc4db8f411e7e0b1521
│   │   └── 1
│   └── f731bebb01b825610631b257585d7cec56b1154441b529f0f9636b3b74554fd750c1ef75cfd1e1e18b7fabedbc53ca3cab3db05209ce020149739a0a14029819
│       └── 1
├── maps
│   └── 155b01e6d21788db91e748932deaca4962ee6f723cc7afd32e82ccf555304499dad06ef5d92dae480903592dec7a1a77ad46d841d455cddb97bfac2bc6d169c7-1
└── meld.db

16 directories, 15 files
> cat /tmp/meld_test/maps/*
7d71b39efc830dd5a6b750a04da9e2eb70a643a1d258dc6597506bd8e179879edb3f6750daeeadca0b0d297771fda17e612f610355c63a60d5c0c87ff39e684d-1
18990ecaf4a799b7119dfef47a51eec51a6ba2c7c376527460d82cae2ec1ceeb23ab037904349405cd24c380aa80bcf737035cd22ff0dada53e7eed30dde4b9f-1
1c54ad4c8d8eb4aeb8a85ac17b2505a1fab357ebbb53837ef753ea202e716470a43749c0e8aa25c8ec519d75677b593e3173a356cd0497aff691ec36b74a533c-1
40dcd0373e6ee3e5987e0df6a6d449078edb858ca7d983d6dd5b0fc520f8748c8156e0f4231b5b90b31dfe4b2887ff35ca6587f7d413b2a0e2ae5841e2c42e6b-1
86aa385dc723c2b2a35e5cba823337be01599326345091b71b3f86283bd7a5a5303b50b5c382f6b3fb4a4b41307a7b0a653bdf0bfb2f9f59b30be916d0dd55ad-1
396814739440b6c50dbd6df3844f6a0296e5d4656dc41c923a45365ba4dbdca050ad0e482075aebc5a587763fc02272dd6112de2ca6332f952d54fbe9a5b5e6f-1
b04d9ac3de1e4e2d3a633832cc71955dcf696039d11a6750e34df8ad2e863afd158b77f9fc0ea589dff1daad5dd9d6df1946e9449ce43f9a38a4bf5c75b83f91-1
5afe942f5ddb73f436c005a377163e1b1675812a77eae2942f0e0bf69b7ff13ede869e3e61240e2e776167745c7ace07545e8969d88b571a5fef192dc0421c6c-1
c3373f98aac47c4332ab89e27a3dbf1af844109b31a16eb0ed2f4b39df924dcb1c31df737f257eb162b68f7b9ac60ac2d5f620e83451bfc4db8f411e7e0b1521-1
6f8390c0bc657f16393eeee71327e6dce63d36136160b7e134cda47af0404ab0af84dbe86623872bda701bb924f05d928eaafe74f054a6bc0cd6211dd596077b-1
f731bebb01b825610631b257585d7cec56b1154441b529f0f9636b3b74554fd750c1ef75cfd1e1e18b7fabedbc53ca3cab3db05209ce020149739a0a14029819-1
92cdce5675765e1606b71f7603170dee57a26adda822a5cd6b86d059f4d0481e83a67130fb00289612b3220ee563fc3b6dcfbeab645bf578744527c77502e3d4-1
3befc5987409a51244955c15972cce01651df9f092a589211899bbf2a2d5b8b680b67bdd9d86af5099abf7b782fb0bfa33f009dd7baa99585d609e562733f1ec-1

依赖关系

~27–36MB
~590K SLoC