树莓派 软件仓库
关键词: raspberry apt reprepro repository
主要内容:
- 树莓派 创建软件源
- 创建 hello deb包
- 使用野火鲁班猫测试仓库
文档参考:
- https://help.ubuntu.com/community/CreateAuthenticatedRepository
- https://blog.csdn.net/weixin_30344131/article/details/98599798
- https://blog.csdn.net/shawzg/article/details/113511859
- https://lanseyujie.com/post/build-ppa-with-reprepro.html
最新地址: https://taotaodiy-raspi.readthedocs.io/en/latest/raspi/repository.html

搭建软件仓库
新建站点
nginx和apache都可以,这里以nginx为例。
局域网中搭建了自己的DNS服务器,所以可以随意设置域名。
创建站点 nginx 参考
搭建DNS dnsmasq 参考
我们照着原来的default的站点搭建一个 www.taotaodiy_raspi.org 。
站点下面有如下文件夹:
pi@taotaodiy:/var/www/www.taotaodiy_raspi.org $ tree
.
├── conf
└── public
└── key
GPG 密钥
GnuPG是由RFC4880(也称为PGP)定义的OpenPGP标准的完整和免费实现。GnuPG允许您对数据和通信进行加密和签名;
它具有一个多功能的密钥管理系统,以及各种公钥目录的访问模块。
GnuPG,也称为GPG,是一个命令行工具,具有易于与其他应用程序集成的特性。有大量的前端应用程序和库可用。
GnuPG还提供了对S/MIME和secureshell(ssh)的支持。
自1997年推出以来,GnuPG是一种自由软件(意味着它尊重您的自由)。
它可以根据GNU通用公共许可证的条款自由使用、修改和分发。
GnuPG的当前版本是2.2.27。其他维护版本请参见下载页。
Gpg4win是GnuPG的Windows版本,具有上下文菜单工具、加密管理器和用于发送和接收标准PGP/MIME邮件的Outlook插件。
Gpg4win的当前版本是3.1.15。
# 安装 gnupg
sudo apt install -y gnupg
# 使用
gpg --full-gen
下面是我设置时的一些log,有些选项不知道怎么选可以参照下:
pi@taotaodiy:~ $ gpg --full-gen
gpg (GnuPG) 2.2.12; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gpg: keybox '/home/pi/.gnupg/pubring.kbx' created
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: taotaodiy
Email address: 1870580572@qq.com
Comment: deb test
You selected this USER-ID:
"taotaodiy (deb test) <1870580572@qq.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /home/pi/.gnupg/trustdb.gpg: trustdb created
gpg: key D9BB1E5CE62063A2 marked as ultimately trusted
gpg: directory '/home/pi/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/pi/.gnupg/openpgp-revocs.d/1753781372F01F569D2B7905D9BB1E5CE62063A2.rev'
public and secret key created and signed.
Note that this key cannot be used for encryption. You may want to use
the command "--edit-key" to generate a subkey for this purpose.
pub rsa4096 2021-06-03 [SC]
2F730DAF31F4BA71569B9BAFCCB2326D2B3491FA
uid taotaodiy (deb test) <1870580572@qq.com>
导出公钥
gpg --list-keys
/home/pi/.gnupg/pubring.kbx
---------------------------
pub rsa4096 2021-06-03 [SC]
2F730DAF31F4BA71569B9BAFCCB2326D2B3491FA
uid [ultimate] taotaodiy (deb test) <1870580572@qq.com>
将公钥导出到 /var/www/www.taotaodiy_raspi.org/public/key/public.key
也就是我们上面创建的目录,后面要用到。
gpg --armor --export 2F730DAF31F4BA71569B9BAFCCB2326D2B3491FA > /var/www/www.taotaodiy_raspi.org/public/key/public.key
pi@taotaodiy:~ $ cat /var/www/www.taotaodiy_raspi.org/public/key/public.key
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGC4wowBEADfJSDLK05gvPJ5VhIocUUH/yZaNqY6brcHuXnjxvn89WVli9gp
LgUOdt5SHRpcjmJitc8565XrlkiR6T4ZxsYNecuKumbBKRlIovFkjqQbBD/ir/rW
JYyZakELT9eR3bDrZrN922sF78IriiUCwcBFjLEeM9DnafT3pEzg6Wh1eeS1GdN/
Fsd9G9/uF2BdyJPGexBHNWC4ZXPh81FoKEjxLz1OnyIHNYf0QwCRD644jBPHhPIn
8fbfYlak812+65SVHsc5MlST+gG7xZRB8mnwernBHWN0FSifiPVLYeo49U46Kqj/
JDUur+RMVF5vVE8vACdHbPTUDC049LQANDUyQKxBbkxCn+2paO5JrpKrQzzg6mBS
tiXrvXWNmYp3Z27HLIxY4CtbJ3NokkeVJHJ3qmuhD2lZMh/4g9nHLAvanyzU7wll
MZuIAt0S0KspRVJZE++4ODmp9gWzIVzGVpULZ/UWc0S4waocfDPhperbWiE/KLp1
ROLCVyJuCHQMpE0MwAWC1Y6RjoInniP2KT68SMtN+Yr2VamvJ6/Q2C/t1ksNUY0O
ARkJ1xfu4Ipx0qRfRibv8nJqmD5kHG5xL1p3F9MoTSxMxBgBeeFWoJ56DFtjWhYS
+D0GCBUo/n621DlSZIX8Ihb9oOdy+kS6hGaiS20gTLjIHYOgChu24IsQiwARAQAB
tCh0YW90YW9kaXkgKGRlYiB0ZXN0KSA8MTg3MDU4MDU3MkBxcS5jb20+iQJOBBMB
CgA4FiEEL3MNrzH0unFWm5uvzLIybSs0kfoFAmC4wowCGwMFCwkIBwIGFQoJCAsC
BBYCAwECHgECF4AACgkQzLIybSs0kfrHFBAAzHPott/2qKUPVAoyVog0FCblzr6T
X4mEORE0qgCO/FsCTOp02VdOKQ99k9qf1Ujmej2awK29tp4UiMCYqq3PqiutH1VS
CpEK7C9Vw+W8bn4YJ5s9FyfGalmOldYRCworOJAfisKTOyR2+pYq6ZZDOcibM9EO
keg7ZVZ+/jqxHbl56KNAPaTgSBc5AVv1z41ItKoicTF/ZabqHvDHd/6isv+QC6hs
T8cwzISYNHH3h1dFyKEV05BteNwTzXztpQgZg92hwMA8mySHuSSIytzHbYOCOt1E
5GlbM99GVLlmKQXf7kMKJmbhhyVPryvX16Y5KOAkwi15qt30WeHBIZGbTxgpix77
bb90HtNKl77xM/2GwSi5A0OUodbQXhNK/49vJl3+RS46ZaBI+jp+OLuxlfYOZ1Fk
8DHb7VTHA+VsOn2Iokrk1Rl9de52CMkifIoBtXv8Vxzxl+YFVcfV+wt4qG6Dku0e
FCoQDMsJBKQc78PomhCgMHQfEVfHgcJdCVfWFHI4FNM1WwqowK3Duzlp2CIU8epl
XriXTqTS9aBJlj2wtAzvivv9WLX7ykbMQVXxhjCaO73ifBCUe2vFdqulv/OgYKC/
ksLtSriuHE8JSfxCYb80pHM2puQ7RGC5dZU6OpO62Xvlr8zzUDX7rNpAlTgqPWiS
SP9O5I+0+DTmuSo=
=TS/B
-----END PGP PUBLIC KEY BLOCK-----
安装仓库管理工具
# 安装仓库管理工具
sudo apt install reprepro
配置文件,文件保到我们前面创建的目录
/var/www/www.taotaodiy_raspi.org/conf/
sudo vim /var/www/www.taotaodiy_raspi.org/conf/distributions
下面是我的配置文件
Origin: taotaodiy
Label: main
Codename: taotaodiy
Suite: stable
Components: main
UDebComponents: main
Architectures: armhf arm64 amd64 source
Description: taotaodiy deb test
SignWith: 2F730DAF31F4BA71569B9BAFCCB2326D2B3491FA
初始化仓库
reprepro --ask-passphrase -Vb /var/www/www.taotaodiy_raspi.org --outdir /var/www/www.taotaodiy_raspi.org/public/taotaodiy
添加 deb 包
deb 是 Unix 系统(其实主要是 Linux)下的安装包,基于 tar
包,因此本身会记录文件的权限(读/写/可执行)以及所有者/用户组。 由于 Unix
类系统对权限、所有者、组的严格要求,而 deb
格式安装包又经常会涉及到系统比较底层的操作,所以权限等的设置尤其重要。
deb 包本身有三部分组成:
- 数据包,包含实际安装的程序数据,文件名为 data.tar.XXX;
- 安装信息及控制脚本包,包含 deb 的安装说明,标识,脚本等,文件名为
control.tar.gz; - 最后一个是 deb 文件的一些二进制数据,包括文件头等信息。
这些一般看不到,在某些软件中打开可以看,deb 本身可以使用不同的压缩方式。
tar
格式并不是一种压缩格式,而是直接把分散的文件和目录集合在一起,并记录其权限等数据信息。
之前提到过的 data.tar.XXX,这里 XXX 就是经过压缩后的后缀名。deb
默认使用的压缩格式为 gzip 格式,所以最常见的就是 data.tar.gz。
常有的压缩格式还有 bzip2 和 lzma,其中 lzma 压缩率最高,但压缩需要的 CPU
资源和时间都比较长。data.tar.gz包含的是实际安装的程序数据,而在安装过程中,该包里的数据会被直接解压到根目录(即
/ ), 因此在打包之前需要根据文件所在位置设置好相应的文件/目录树。 而
control.tar.gz 则包含了一个 deb 安装的时候所需要的控制信息。
一般有 5 个文件:
- control,用了记录软件标识,版本号,平台,依赖信息等数据;
- preinst,在解包data.tar.gz 前运行的脚本;
- postinst,在解包数据后运行的脚本;
- prerm,卸载时,在删除文件之前运行的脚本;
- postrm,在删除文件之后运行的脚本;
在 Cydia 系统中,Cydia 的作者 Saurik
另外添加了一个脚本,extrainst_,作用与 postinst 类似。
下面我们自己制作一个软件包放到我们的软件仓库。
------------------------------写一个简单的
hello world 程序。
#include <stdio.h>
int main()
{
printf("hello raspi, I am taotaodiy\r\n");
return 0;
}
编译 hello world ,由于本身树莓派arm架构,就不再需要搭建交叉编译环境。
gcc hello.c -o hello
构建deb包,我直接弄了一个脚本,当然的话完全可以手动拷贝,用命令打包。
Version=1.0.0.0
Package=hello-test_1.0.0.0_armhf.deb
# if [ ! -e hello ]; then
# echo "Please compile the program first"
# exit
# fi
echo "Package ${Package}"
echo "Version ${Version}"
echo -e "Copy temporary files"
#deb包 临时目录
PackageDir=hellodeb
mkdir -p $PackageDir
rm -rf $Package
# App 依赖的库
# APPLIB=$PackageDir/usr/lib/
# mkdir -p ${APPLIB}
#App 资源文件和配置文件
APPINSTALL=$PackageDir/usr/local/hello
mkdir -p ${APPINSTALL}
cp -r hello ${APPINSTALL}
#deb控制信息
echo -e "Creating deb control information"
# systemd执行qt run.sh
mkdir -p $PackageDir/lib/systemd/system
cat >$PackageDir/lib/systemd/system/hello.service<<EOF
[Unit]
Description = taotaodiy
[Service]
ExecStart = /usr/local/hello
Type = simple
[Install]
WantedBy = multi-user.target
EOF
mkdir -p $PackageDir/DEBIAN
# 添加程序信息
cat >$PackageDir/DEBIAN/control<<EOF
Package: taotaodiy-hello
Version: $Version
Section: utils
Priority: optional
Architecture: armhf
Depends:
Installed-Size: 512
Maintainer: taotaodiy <www.taotaodiy.com>
Description: deb test
EOF
# 添加自启动服务
cat >$PackageDir/DEBIAN/postinst<<EOF
#!/bin/bash
systemctl enable hello
EOF
chmod 775 $PackageDir/DEBIAN/postinst
#打包
echo -e "Package..."
dpkg -b $PackageDir $Package
rm -rf $PackageDir
echo -e "Package complete"
直接执行脚本 就会生成一个 hello-test_1.0.0.0_armhf.deb,
当然同级目录需要有上面编译好的hello可执行文件
# 打包
./dpkg.sh
将打包好的 deb 包添加到软件仓库中。
又是一个脚本,如下,当然也可以直接用命令: reprepro --ask-passphrase
-Vb . includedeb taotaodiy xxx.deb
#!/bin/bash
usage () {
echo "usage: ./add_deb.sh [debfile]"
echo " ./add_deb hello.deb "
}
if [ "$1" = "--help" ] ; then
usage
exit
fi
reprepro --ask-passphrase -Vb . includedeb taotaodiy $1
执行效果
pi@taotaodiy:/var/www/www.taotaodiy_raspi.org $ ./add_deb.sh hellotest/hello-test_1.0.0.0_armhf.deb
hellotest/hello-test_1.0.0.0_armhf.deb: component guessed as 'main'
Created directory "./pool"
Created directory "./pool/main"
Created directory "./pool/main/t"
Created directory "./pool/main/t/taotaodiy-hello"
Exporting indices...
Created directory "./dists"
Created directory "./dists/taotaodiy"
Created directory "./dists/taotaodiy/main"
Created directory "./dists/taotaodiy/main/binary-armhf"
Created directory "./dists/taotaodiy/main/debian-installer"
Created directory "./dists/taotaodiy/main/debian-installer/binary-armhf"
Created directory "./dists/taotaodiy/main/binary-arm64"
Created directory "./dists/taotaodiy/main/debian-installer/binary-arm64"
Created directory "./dists/taotaodiy/main/binary-amd64"
Created directory "./dists/taotaodiy/main/debian-installer/binary-amd64"
Created directory "./dists/taotaodiy/main/source"
Successfully created './dists/taotaodiy/Release.gpg.new'
Successfully created './dists/taotaodiy/InRelease.new'
pi@taotaodiy:/var/www/www.taotaodiy_raspi.org $
下面就是我们最终的仓库目录,hellotest是临时创建的。
pi@taotaodiy:/var/www/www.taotaodiy_raspi.org $ tree
.
├── add_deb.sh
├── conf
│ └── distributions
├── db
│ ├── checksums.db
│ ├── contents.cache.db
│ ├── packages.db
│ ├── references.db
│ ├── release.caches.db
│ └── version
├── dists
│ └── taotaodiy
│ ├── InRelease
│ ├── main
│ │ ├── binary-amd64
│ │ │ ├── Packages
│ │ │ ├── Packages.gz
│ │ │ └── Release
│ │ ├── binary-arm64
│ │ │ ├── Packages
│ │ │ ├── Packages.gz
│ │ │ └── Release
│ │ ├── binary-armhf
│ │ │ ├── Packages
│ │ │ ├── Packages.gz
│ │ │ └── Release
│ │ ├── debian-installer
│ │ │ ├── binary-amd64
│ │ │ │ ├── Packages
│ │ │ │ └── Packages.gz
│ │ │ ├── binary-arm64
│ │ │ │ ├── Packages
│ │ │ │ └── Packages.gz
│ │ │ └── binary-armhf
│ │ │ ├── Packages
│ │ │ └── Packages.gz
│ │ └── source
│ │ ├── Release
│ │ └── Sources.gz
│ ├── Release
│ └── Release.gpg
├── hellotest
│ ├── dpkg.sh
│ ├── hello
│ ├── hello.c
│ └── hello-test_1.0.0.0_armhf.deb
├── index.php
├── pool
│ └── main
│ └── t
│ └── taotaodiy-hello
│ └── taotaodiy-hello_1.0.0.0_armhf.deb
├── public
│ └── key
│ └── public.key
└── sub_deb.sh
测试源
Debian采用集中式的软件仓库机制,将各式各样
的软件包分门别类地存放在软件仓库中,进行有效地组织和管理。
然后,将软件仓库置于许许多多的镜像服务器中,并保持基本一致。这样,所有的Debian用户随时都能获得最新版本的安装软件包。
因此,对于用户,这些镜像服务器就是他们的软件源(Reposity)。
然而,由于每位用户所处的网络环境不同,不可能随意地访问各镜像站点。
为了能够有选择地访问,在Debian系统中,使用软件源配置文件/etc/apt/sources.list列出最合适访问的镜像站点地址。
自建软件源
deb [arch=armhf] http://taotaodiy_raspi.org/ taotaodiy main
即使这样,软件源配置文件只是告知Debian系统
可以访问的镜像站点地址,但那些镜像站点具体都拥有什么软件资源并不清楚。
软件包管理系统使用一个私有数据库跟踪列表中软件包的当前状态:已安装、未安装或可安装。
apt-get通过该数据库来确定如何安装用户想用的软件包以及正常运行软件包所必须的其它关联包(软件包依赖关系),这大大简化了安装和卸载软件包的过程。
更新软件包管理系统时将扫描/etc/apt/sources.list文件中所指路径中的软件包列表文件,以便本地主机查询。
更新包管理工具数据库列表命令
sudo apt-get update
安装软件命令
# xxx为你要安装的软件包。
sudo apt-get install xxx
这时,apt会扫描它的数据库找到最新的版本的软件包,
并将它从sources.list中所指的地方下载到本地。
如果该软件包需要其它软件包才能正常运行,
这时apt会做关联性检查并自动安装所关联软件包。
这下我们的软件包和软件源都创建好了。
软件仓库是配置在树莓派上的,当做服务器,
然后使用野火鲁班猫开发板作为客户端去安装软件仓库中的软件,当然反过来也可以。
这里第一步需要获取到仓库的公钥,使用wget安装。
# 安装 wget
sudo apt install wget
# 获取公钥
wget -O - http://www.taotaodiy_raspi.org/public/key/public.key | sudo apt-key add -
debian@npi:~$ wget -O - http://www.taotaodiy_raspi.org/public/key/public.key | sudo apt-key add -
--2021-06-03 22:16:00-- http://www.taotaodiy_raspi.org/public/key/public.key
Resolving www.taotaodiy_raspi.org (www.taotaodiy_raspi.org)... 192.168.31.80
Connecting to www.taotaodiy_raspi.org (www.taotaodiy_raspi.org)|192.168.31.80|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1656 (1.6K) [application/octet-stream]
Saving to: 'STDOUT'
- 100%[===================================================>] 1.62K --.-KB/s in 0s
2021-06-03 22:16:00 (21.5 MB/s) - written to stdout [1656/1656]
OK
然后更改我们的本地源,源通常保存在 /etc/apt/sources.list
sudo vi /etc/apt/sources.list
添加我们自建的仓库的源
deb [arch=armhf] http://taotaodiy_raspi.org/ taotaodiy main
更新本地源
debian@npi:~$ sudo apt update
Get:1 http://taotaodiy_raspi.org taotaodiy InRelease [5559 B]
Get:2 http://taotaodiy_raspi.org taotaodiy/main armhf Packages [316 B]
Hit:3 http://deb.debian.org/debian buster InRelease
Fetched 5875 B in 18s (334 B/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
1 package can be upgraded. Run 'apt list --upgradable' to see it.
debian@npi:~$
安装我们前面自己创建的deb包
debian@npi:~$ sudo apt install taotaodiy-hello
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
taotaodiy-hello
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 2908 B of archives.
After this operation, 524 kB of additional disk space will be used.
Get:1 http://taotaodiy_raspi.org taotaodiy/main armhf taotaodiy-hello armhf 1.0.0.0 [2908 B]
Fetched 2908 B in 0s (70.8 kB/s)
Selecting previously unselected package taotaodiy-hello.
(Reading database ... 12756 files and directories currently installed.)
Preparing to unpack .../taotaodiy-hello_1.0.0.0_armhf.deb ...
Unpacking taotaodiy-hello (1.0.0.0) ...
Setting up taotaodiy-hello (1.0.0.0) ...
Created symlink /etc/systemd/system/multi-user.target.wants/hello.service → /lib/systemd/system/hello.service.
debian@npi:~$
检查安装结果。
debian@npi:~$ cd /usr/local/hello/
debian@npi:/usr/local/hello$ ./hello
hello raspi, I am taotaodiy
debian@npi:/usr/local/hello$
在创建deb包的时候,我们在安装包中加入了开机自动启动的配置,重启开发板hello也会运行。
本文详细介绍了如何在树莓派上搭建软件仓库,包括新建站点、配置GPG密钥、导出公钥、安装仓库管理工具reprepro,以及添加deb包和测试源的过程。此外,还提到了软件包的格式和结构,以及如何在开发板上测试自建仓库。


被折叠的 条评论
为什么被折叠?



