https://github.com/anduin2017/learnapt
https://github.com/anduin2017/learnapt
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/anduin2017/learnapt
- Owner: Anduin2017
- Created: 2025-03-20T16:56:29.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-03-20T16:56:32.000Z (about 1 year ago)
- Last Synced: 2025-03-30T00:27:06.764Z (about 1 year ago)
- Language: Python
- Size: 17.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Learn Apt and Deb
我写了一个有意思的小程序。它的名字叫 apt-vis。它是用 Python 写的。它的作用是可视化一下 apt 包的依赖关系。
我已经把它写完了。但是,我想把这个小程序发给我的好朋友们,让他们可以下载。我的包依赖了 apt、python3 和 bash。
apt-vis 文件的开头是这样的:
```python
#!/usr/bin/env python3
import subprocess
from collections import defaultdict, deque
from concurrent.futures import ThreadPoolExecutor
import threading
import os
import sys
import webbrowser
import urllib.request
```
我想,如果可以把它放置在 /usr/local/bin/apt-vis 就算是安装成功了。
考虑到我的所有朋友都是 debian 用户,所以我计划这么干:
* 首先将 apt-vis 文件和相关的其它文件准备好,放在一个文件夹里。
* 然后使用什么工具,把它弄成一个 deb 文件。
* 我将签名后的 deb 文件,搭建出来一个 apt 服务器。
* 我使用一个静态文件的 Web 服务器,承载这个 apt 服务器。
* 签名仓库的元数据(Release 文件)而不是直接对 .deb 包做签名。
* 我告诉我的好朋友,如何信任我的 key,并且添加我的 apt 源。
* 我告诉我的好朋友,如何安装这个 apt 包。
但是,我暂时想先测测,在我自己电脑上。所以我暂时不打算真的签名。
我希望我的朋友的机器这么配置(暂时只考虑支持 Ubuntu Oracular 版本。我的所有组件都放 main 里):
/etc/apt/sources.list.d/anduins-server.list
## Apt Server 的约定
因为我刚刚学习了 apt 服务器建设的最佳实践,也就是当客户端写了
```bash
deb http://localhost/path/ distro aaa bbb ccc ddd
```
时,apt 会去请求:
* http://localhost/path/dist/distro/aaa/binary-<你的架构>/*
* http://localhost/path/dist/distro/bbb/binary-<你的架构>/*
* http://localhost/path/dist/distro/ccc/binary-<你的架构>/*
* http://localhost/path/dist/distro/ddd/binary-<你的架构>/*
其中,* 的地方需要存储 Packages, Packages.gz, Packages.xz 文件。其实它们内容是相同的。
APT 在更新源时会尝试下载 Packages.xz 或 Packages.gz 优先级较高,找不到才会回退到 Packages。
而这个目录
* http://localhost/path/dist/distro/*
这个目录下的 * 的地方,需要存储 Release,InRelease文件,用于校验仓库的签名。
* 如果仓库同时提供 InRelease 和 Release + Release.gpg,APT 会优先使用 InRelease。
* 如果只提供 Release 和 Release.gpg,APT 也可以验证签名。
所以我打算在客户端使用这个结构:
```
deb [trusted=yes] http://localhost:8080/ubuntu/ oracular main
```
## 生成 Deb 文件
为了生成 deb 文件,我需要一个目录结构。我把 apt-vis 文件放在 /usr/local/bin 下面。
```bash
```bash
anduin@anduin-lunar:~/Desktop/LearnDeb$ tree
.
└── apt-vis_1.0.0-1
├── DEBIAN
│ └── control
└── usr
└── local
└── bin
└── apt-vis
```
如果需要生成 deb 文件,我直接在下面执行:
```bash
dpkg-deb --build apt-vis_1.0.0-1
```
## 搭建 Apt 服务器
我的目录结构已经拼成了:
```bash
anduin@anduin-lunar:~/Desktop/LearnDeb$ tree
.
├── apt-vis_1.0.0-1
│ ├── DEBIAN
│ │ └── control
│ └── usr
│ └── local
│ └── bin
│ └── apt-vis
└── WebRoot
└── ubuntu
├── dists
│ └── oracular
│ ├── main
│ │ └── binary-amd64
│ │ ├── Packages
│ │ ├── Packages.gz
│ │ └── Packages.xz
│ └── Release
└── pool
└── main
└── a
└── apt-vis_1.0.0-1.deb
15 directories, 7 files
```
如果我需要得到 Packages 的文件:
```bash
# Generate packages
cd ~/Desktop/LearnDeb/WebRoot/ubuntu
dpkg-scanpackages pool/ /dev/null > dists/oracular/main/binary-amd64/Packages
gzip -9c dists/oracular/main/binary-amd64/Packages > dists/oracular/main/binary-amd64/Packages.gz
xz -9 < dists/oracular/main/binary-amd64/Packages > dists/oracular/main/binary-amd64/Packages.xz
# Generate release
cd ~/Desktop/LearnDeb/WebRoot/ubuntu/dists/oracular
apt-ftparchive release . > Release
```
接下来,我只需要去把 WebRoot 拷贝到静态文件 Web 服务器下面就可以了。如果我需要新增包,我直接放在 pool/main 的对应目录下就可以了。
我这个服务器除了要server这个apt-vis,我还要 serve 其它我写的一些仓库。所以服务器就是 Anduin 的作品集。暂时只支持 Ubuntu Oracular AMD64。
## 客户端配置
我需要在客户端配置 /etc/apt/sources.list.d/anduin.list 文件:
```bash
deb [trusted=yes] http://localhost:8080/ubuntu/ oracular main
```
然后我需要在客户端执行:
```bash
sudo apt update
sudo apt install apt-vis
```
我们会观察到 apt-vis 被安装了。此时一切都是正常的。