This is an article written by my student Xincheng Ren. He helps me setup the Ubuntu software repository for PicoScenes.
本文将介绍如何在linux服务器上构建一个属于你自己的第三方软件仓库(Personal Package Archives,简称PPA),构建完成之后,其他人将可以像安装linux官方源中的软件那样在命令行中安装你定制的软件。而和官方官方软件仓库稍微不同的是,需要首先添加你的软件源,之后便可以使用sudo apt update && sudo apt install xxx来进行安装你的软件。
1.操作平台
安装了Ubuntu20.04的服务器
2.软件仓库简介
很多人可能都在自己的电脑上更改过自己的软件源,以获得更快的软件下载速度,更改不同的源就对应着不同的软件仓库。比如Linux mint可以打开软件源(Software Resources),通过测速和更改镜像源来比较获得一个更快的软件下载源,如图1所示:

更改源之后,可以执行sudo apt update && sudo apt upgrade,可以发现下载软件速度明显提高。在更改官方源,update和upgrade时,在系统内部都进行了什么操作呢?
三步操作都各自完成了一个具体的操作:
1.更改官方源。每一个linux系统都有一个或者多个存放源的文件,比如在Linux mint20.04中,文件的完整路径为(对于不同的linux发行版存放软件源的文件可能有所区别,需要根据自己的系统具体查询):/etc/apt/sources.list.d/official-package-repositories.list,在official-package-repositories.list中的内容如下(假设主要(ulyana)源和基础(focal)源均改为清华源):
deb https://mirrors.tuna.tsinghua.edu.cn/linuxmint ulyana main upstream import backport deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal main restricted universe multiverse deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal-updates main restricted universe multiverse deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal-backports main restricted universe multiverse deb http://security.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse deb http://archive.canonical.com/ubuntu/ focal partner
由上可知,更改源是更改了第一行,第三四五行的内容。更改之后update和upgrade时查询软件仓库的地址即为清华源所对应的目录。而对于一些不在清华源的软件,则会从ubuntu官方的源仓库来进行安装。
2.update。在更改源之后进行,具体操作为查询软件仓库中的Release文件,InRelease文件以及文件的一些配置信息,数字签名等等。最重要的一点,对比软件仓库中的软件信息文件,是否有版本更新,然后在update查询之后显示有多少软件可以进行更新。
3.upgrade。在update更新之后,如果有软件可以更新,则从所更改的软件源来进行下载安装所有可以更新的软件。
假设你要构建一个包含三个deb包的软件仓库,分别first.deb,second.deb和single.deb,架构全部为amd64,其中的依赖关系为second.deb依赖first.deb,而first.deb和single.deb不依赖任何包。对于常见的linux软件仓库来说,其完成构建时,软件仓库的目录大致如下:
├── dists │ └── stable │ ├── Contents-amd64.gz │ ├── Release │ ├── Release.gpg │ ├── apt.conf │ └── main │ └── binary-amd64 │ ├── Packages │ └── Packages.gz ├── pool │ └── main │ ├── first.deb │ ├── second.deb │ ├── single.deb └── project └── ppa-public-key.gpg
典型的ubuntu仓库有dists目录和pool目录,dists中存放关于软件包的一些信息,如依赖关系,文件大小,所需要的系统架构等等;pool中存放实际要安装的deb包,实际的软件仓库一般main一个目录,可以按照自己的需要进行添加。对于大多数非官方仓库,会多一个project目录,其中存放服务器上导出的公钥文件,当公钥文件导入到系统中时,系统才会认为来自这个服务器的文件是安全的。
更改源可以简单理解为更改安装软件的地址,从不同的网络地址下载软件的速度是不一样的;update则可以简单理解为查询软件包的一系列参数。upgrade和install则可以理解为从安装软件的地址下载软件并安装在本机。从软件安装的角度来说,上述三步是简化了安装软件的步骤,这和你从软件源地址下载deb包点击安装得到的效果是一样的。
3.配置信息生成
假设你在服务器端已经有了first.deb,second.deb和single.deb这三个deb包。则对应于上一节的三个目录dists,pool和project我们已经完成了pool目录中文件的生成。接下来我们需要在服务器端进行一些修改,从而来生成dists和project中的内容。
1.准备操作
1.安装apache2服务器,具体操作参考上一文。
2.创建软件仓库所需要的文件夹,并将前面准备的三个deb包复制到/var/www/html/pool/main目录,预期的效果为:
上层目录为/var/www/html ├── dists │ └── stable │ └── main │ └── binary-amd64 ├── pool │ └── main │ ├── first.deb │ ├── second.deb │ ├── single.deb └── project
3.安装配置信息生成文件必备软件:
# 安装gpg $ sudo apt install gpg # 安装rng-tools $ sudo apt install rng-tools
gpg可以生成服务器公钥,并导出公钥文件,从而供其他用户导入。rng-tools可以加快gpg生成公钥时产生随机值的过程,否则可能会很久甚至服务器未响应都不会产生所需要的随机值。
4.确保你的服务器上有压缩软件,例如gzip。
5.假设下文中在服务器上的操作均为管理员用户。
2.dists目录中信息文件的生成
以下的操作中,不做特殊说明,均在/var/www/html目录下进行,即在当前目录下列出文件或者查询工作目录的话,结果如下:
$ ls dists pool project $ pwd /var/www/html
1.packages文件生成
调用格式为:apt-ftparchive packages deb包所在目录 > Packages文件路径和文件名。
例如如下命令格式:
# 生成packages文件 $ apt-ftparchive packages pool/main > dists/stable/main/binary-amd64/Packages
运行之后会在/var/www/html/dists/stable/main/binary-amd64目录下生成一个Packages文件。Packages中的内容类似如下:
Package: picoscenes-driver Architecture: amd64 Version: 20191229 Priority: optional Section: network Source: picoscenes-driver Maintainer: Zhiping Jiang <zpj@xidian.edu.cn> Installed-Size: 2763 Depends: linux-image-5.4.0-45-generic Filename: pool/main/picoscenes-driver-20191229.deb Size: 619152 MD5sum: 58b9342be5bcea08c5b66cb2288c2fc7 SHA1: bba0cf6070383b0b5c1e455dfc04b1f2e5af493f SHA256: 2faeb2d3dadaa6507ba1dc380ce5e23889263ed03d21a654b2fc83954a3530d8 SHA512: 5ddd2710086f5c441c97e5e011fec6317e412ba46e9845f1f758b5f5346675126dc1bff5bc98c815c6384bd1e6f2e8f6dc4f1b486beacf04f8c20ee67a8db259 Homepage: https://zpj.io/PicoScenes Description: PicoScenes Driver This package contains the customized Qualcomm Atheros ar9300 (QCA9300) and Intel Wireless Link 5300 (IWL5300) Wi-Fi drivers for PicoScenes system. To reduce the maintainance work, this driver is ONLY compatible with kernel verion: 5.4.0-45-generic. Package: picoscenes-platform Architecture: amd64 Version: 2020.0816.1248 Priority: optional Section: devel Maintainer: Zhiping Jiang<zpj@xidian.edu.cn> Installed-Size: 10340 Depends: picoscenes-driver, build-essential, libboost-all-dev, openjdk-8-jre, libcpprest-dev, libssl-dev, net-tools, p7zip-full, hostapd, cpufrequtils, libsodium23, libfmt-dev, uhd-host, libopenblas-base Filename: pool/main/picoscenes-platform-2020.0816.1248-Linux.deb Size: 3395486 MD5sum: 4888b72822ee635507b75c9cb3c7aa8e SHA1: 16ba5232fbc734e3da77af0685a9e092a0a6c0bd SHA256: 6ddee9f2936eb25c341f717aeaff67d69eb39d43f7e1e9227f382018697e0238 SHA512: 1dcaa0b05fbc8e2cf0893b18279d3446e693762e14b8b9981079b3da3edf7b6992fb71bfb350e39e22b179144f1118ce370bd3f70ed2f1eb1ce9361c1055a026 Homepage: https://zpj.io/PicoScenes Description: PicoScenes Platform PicoScenes Platform, depending on PicoScenes Driver, wraps all the low-level Wi-Fi NIC controls into a bunch of powerful APIs for the atop PicoScenes plug-in subsystem. Package: picoscenes-plugins-demo-rxsbroadcaster-echoprobe Architecture: amd64 Version: 20.0718.0252 Priority: optional Section: devel Maintainer: Zhiping Jiang<zpj@xidian.edu.cn> Installed-Size: 1153 Depends: picoscenes-platform Filename: pool/main/picoscenes-plugins-demo-rxsbroadcaster-echoprobe-20.0718.0252-Linux.deb Size: 349528 MD5sum: 2b61bf7bfced4632148b79d87908d13c SHA1: 418452d5f64342e960aa35cee5bb59ea8c401794 SHA256: 063f67584a2fcdcfb46c5b9a21eb99d4af19c9ec104d0b40c8f0a2078ba44a53 SHA512: cbb301e0bc46783966b7b719f8c99f8e668efdf64b3a26b3ae89016762135f0cae52a3a20b20e193dcd77145074896f51acc8f83a1e41d4a87cc7b412479d725 Homepage: https://zpj.io/PicoScenes Description: Three Sample Plug-Ins of PicoScenes System. The plug-ins are: EchoProbe, us-level round-trip CSI measurement in UWB spectrum; RXS-Broadcaster, RxS data forwarding to the remote via UDP protocol; and Demo, the sample code of PicoScenes Plug-In Development Kit (PSPDK).
对于你自己的deb仓库,生成的文件会有所不同,但是所拥有的参数都是类似的,例如Package,Source, Version,Architecture,和Maintainer等等,这些参数都是在deb文件中的control文件中的信息。还有一些是在control文件中所没有的,例如Filename,Size,MD5sum等等,这些都是apt-ftarchive packages所新生成的,主要起了对比文件信息的作用,例如如果软件仓库中的文件大小和packages文件中登记的文件大小不一样的时候,会报错,如下所示:
Get:1 https://服务器地址/ stable main amd64 picoscenes-driver amd64 20191229 [619 kB] Err:1 https://服务器地址/ stable main amd64 picoscenes-driver amd64 20191229 Hash Sum mismatch Hashes of expected file: - SHA512:5ddd2710086f5c441c97e5e011fec6317e412ba46e9845f1f758b5f5346675126dc1bff5bc98c815c6384bd1e6f2e8f6dc4f1b486beacf04f8c20ee67a8db259 - SHA256:2faeb2d3dadaa6507ba1dc380ce5e23889263ed03d21a654b2fc83954a3530d8 - SHA1:bba0cf6070383b0b5c1e455dfc04b1f2e5af493f [weak] - MD5Sum:58b9342be5bcea08c5b66cb2288c2fc7 [weak] - Filesize:619152 [weak] Hashes of received file: - SHA512:f3bf69496b2f86f9a2a6d69baa3a19cacba20e7125251c922894725603a4e11cec764200ec8207d000033880086530a47e632dcadef0979cf716d7d05e377cf7 - SHA256:aa768f83bca305c3979399589bbdc0521804401017dda001ea9171517291cedb - SHA1:1b03162a6336a58d253b8f919be041b360b04ae7 [weak] - MD5Sum:83d4771518c082731bd40e253af4e7f8 [weak] - Filesize:618820 [weak] Last modification reported: Sat, 15 Aug 2020 02:11:56 +0000 E: Failed to fetch https://服务器地址/pool/main/picoscenes-driver-20191229.deb Hash Sum mismatch Hashes of expected file: - SHA512:5ddd2710086f5c441c97e5e011fec6317e412ba46e9845f1f758b5f5346675126dc1bff5bc98c815c6384bd1e6f2e8f6dc4f1b486beacf04f8c20ee67a8db259 - SHA256:2faeb2d3dadaa6507ba1dc380ce5e23889263ed03d21a654b2fc83954a3530d8 - SHA1:bba0cf6070383b0b5c1e455dfc04b1f2e5af493f [weak] - MD5Sum:58b9342be5bcea08c5b66cb2288c2fc7 [weak] - Filesize:619152 [weak] Hashes of received file: - SHA512:f3bf69496b2f86f9a2a6d69baa3a19cacba20e7125251c922894725603a4e11cec764200ec8207d000033880086530a47e632dcadef0979cf716d7d05e377cf7 - SHA256:aa768f83bca305c3979399589bbdc0521804401017dda001ea9171517291cedb - SHA1:1b03162a6336a58d253b8f919be041b360b04ae7 [weak] - MD5Sum:83d4771518c082731bd40e253af4e7f8 [weak] - Filesize:618820 [weak] Last modification reported: Sat, 15 Aug 2020 02:11:56 +0000 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
在Packages文件生成之后,还要做一件事,将Packages文件压缩,存放在和Packages文件相同的目录中,如下:
# 生成压缩包 $ gzip -9c dists/stable/main/binary-amd64/Packages > dists/stable/main/binary-amd64/Packages.gz
在本小节完成后,dists目录中的内容如下:
├── dists │ └── stable │ └── main │ └── binary-amd64 │ ├── Packages │ └── Packages.gz
2.contents文件生成
调用格式为:apt-ftparchive contents deb包所在目录 > contents文件路径和文件名。由于最终需要的是一个压缩文件,在上述命令进行调整,添加一个压缩文件的一步。
调整后的命令格式参考如下:
# 生成contents文件 $ apt-ftparchive contents pool/main | gzip -9c > dists/stable/Contents-amd64.gz
由于在本文中的deb包架构为amd64,故需要生成一个名为Contents-amd64.gz,可根据自己的软件架构生成Contents-i386.gz或者Contents-armhf.gz。
contents文件中的内容为目录中的deb包中所有安装文件的绝对路径和文件名以及属于哪个deb包。如下所示为contents文件片段:
... usr/include/gmock/gmock-actions.h picoscenes-platform usr/include/gmock/gmock-cardinalities.h picoscenes-platform usr/include/gmock/gmock-function-mocker.h picoscenes-platform usr/include/gmock/gmock-generated-actions.h picoscenes-platform ... usr/local/PicoScenes/plugins/libPDK-EchoProbe.so picoscenes-plugins-demo-rxsbroadcaster-echoprobe usr/local/PicoScenes/plugins/libPDK-demo.so picoscenes-plugins-demo-rxsbroadcaster-echoprobe usr/local/PicoScenes/plugins/libPlugIn-RXSBroadcaster.so picoscenes-plugins-demo-rxsbroadcaster-echoprobe ...
在本小节完成后,dists目录中的内容如下:
├── dists │ └── stable │ ├── Contents-amd64.gz │ └── main │ └── binary-amd64 │ ├── Packages │ └── Packages.gz
3.apt.conf文件制作
atp.conf文件中主要包含了一些软件包的信息,可以参考如下形式,根据自己的需求创建apt.conf文件。若需要详细配置,则可以参考apt官方说明文档进行创建apt.conf文件,最终将apt.conf文件复制到和Contents-amd64.gz同样的目录,apt.conf参考内容如下:
APT::FTPArchive::Release { Origin "ubuntu"; Label "Ubuntu"; Suite "stable"; Codename "ulyana"; Versin "1.0"; Architecture "amd64"; Components "main"; Description "PicoScenes driver, platform, plugins and all."; };
在本小节完成后,dists目录中的内容如下:
├── dists │ └── stable │ ├── apt.conf │ ├── Contents-amd64.gz │ └── main │ └── binary-amd64 │ ├── Packages │ └── Packages.gz
4.release文件生成
调用格式为:apt-ftparchive -c apt.conf路径 release dists下对应软件目录 > dists下对应软件目录/Release。命令参考格式如下:
# 生成release文件 $ apt-ftparchive -c dists/stable/apt.conf release dists/stable > dists/stable/Release
生成的Release文件内容形式如下所示:
Codename: ulyana Components: main Date: Tue, 08 Sep 2020 03:36:43 +0000 Description: PicoScenes driver, platform, plugins and all. Label: Ubuntu Origin: ubuntu Suite: stable MD5Sum: 4de5291165f3ddfdabd6b177f71a9d65 1749 Contents-amd64.gz 1468f7b3232a231f6a0680036e21fd17 174 Release ac956e2363b5d057c9fd507ba17b6f79 2860 main/binary-amd64/Packages 26f29795d563b5cab3bdd0b84c4b238e 1466 main/binary-amd64/Packages.gz SHA1: 38e46946208c73452b9208de8617e8904fb6b5bc 1749 Contents-amd64.gz 31400d36f372bdae9de45e550a8cc657c6d659dc 174 Release b9ee4d61fdba4a8fa6894dddd608485cf2ddcd21 2860 main/binary-amd64/Packages 3497f0c023366edbba492473e8307c4c26e76a3b 1466 main/binary-amd64/Packages.gz SHA256: addbcd1a4ef90fa4de802db680e0abb79552bf45697ef20533ab7f38b8988215 1749 Contents-amd64.gz 7ddf81179c6d143f714e443c970e8b1390e1ac17462b070bf03eba68056d083a 174 Release 3729fad154cf8748e03dd7356985139cabf98eac347c3c9cf686bc67e1795fce 2860 main/binary-amd64/Packages 74c1888a9f6b82295dcea66b78f9f123ba87ab766d49652859c0c4e66aab5d9b 1466 main/binary-amd64/Packages.gz SHA512: a86ff11bade4672403bd932eb092376fefb4bbc39774e234ec7c2ea48c5c62e3d4becd98c8c7f3abc1fb418df5b6c5981af69989a4df72b6bab3cc756e1a50a1 1749 Contents-amd64.gz 4ec161deb1ad5107974ef7939e0a84f9650dd085633f8265796efc101c1b00058f5138a494d08594d11f9f18f45597cc73c78ebce7cd784090d7ff78052ee97d 174 Release 3034171a9c06a3792915823019b9193ec62e5a3b50962330807aed677484b712ee79cd70a75e266fa41f246954180e315636e5a73456875abd1be407e64d1af2 2860 main/binary-amd64/Packages 9175417730f4988ae29bda88af33fafae2dcbd428f194a34d150cd55a7cd5fcbaa360e54d9cbd874af9c9e923fa2ce529ebce2ae868e8e68ecc3287927421c5b 1466 main/binary-amd64/Packages.gz
在本小节完成后,dists目录中的内容如下:
├── dists │ └── stable │ ├── apt.conf │ ├── Contents-amd64.gz │ ├── main │ │ └── binary-amd64 │ │ ├── Packages │ │ └── Packages.gz │ └── Release
5.Release.gpg文件
最终Release.gpg文件是要生成在和Release的同一目录下,同样也是dists目录下的一个文件。但是由于是需要用到gpg软件进行操作,目前还没使用到gpg软件,所以将生成Release.gpg文件的操作放在下一章。
3. project目录中信息文件的生成
以下的操作中,若不做特殊说明,均在/var/www/html目录下进行。
1.ppa-public-key.gpg公钥导出
注意:在project目录下的ppa-public-key.gpg文件和之前提到的Release.gpg是不同的两个文件。
目前,你已经安装了gpg和rng-tools,使用gpg –list-keys可以查看当前所生成过的密钥,当未生成过密钥时,显示如下:
# 显示密钥 $ gpg --list-keys $
显示为空,则我们需要在服务器端生成一个密钥,使用gpg –full-generate-key来生成密钥,如下所示为生成过程:
# 生成密钥 $ gpg --full-generate-key gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. 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) (14) Existing key from card Your selection? 1(用户输入确认) 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: PPA-Demo(用户输入确认) Email address: XX@XXX.com(用户输入确认) Comment: NO(用户输入确认) You selected this USER-ID: "PPA-Demo (NO) <XX@XXX.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. (会弹出一个窗口让你提示输入公钥密码以及重复一遍密码,如下) │ Please enter the passphrase to │ │ protect your new key │ │ │ │ Passphrase: ________________________________________ │ │ │ │ <OK> <Cancel> │ (假设输入的密码为PPAPwd并确认) 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. (上述显示在产生随机值,由于之前已经安装了rng-tools,所以产生随机值花费的时间不多,若未安装rng-tools,则此过程会十分漫长) gpg: key 7B2677D04250EA0E marked as ultimately trusted gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/DF431E9AFB953A977D83071A7B2677D04250EA0E.rev' public and secret key created and signed. pub rsa4096 2020-09-08 [SC] DF431E9AFB953A977D83071A7B2677D04250EA0E uid PPA-Demo (NO) <XX@XXX.com> sub rsa4096 2020-09-08 [E]
此时再次显示密钥:
# 显示公钥 $ gpg --list-keys /root/.gnupg/pubring.kbx ------------------------ pub rsa4096 2020-09-08 [SC] DF431E9AFB953A977D83071A7B2677D04250EA0E uid [ultimate] PPA-Demo (NO) <XX@XXX.com> sub rsa4096 2020-09-08 [E]
至此,我们完成了在服务器端生成密钥的操作,接下来就要导出密钥文件到project,操作命令如下:
# 导出公钥文件 $ gpg --export > project/ppa-public-key.gpg
在本小节完成后,project目录中的内容如下:
└── project └── ppa-public-key.gpg
2.Release.gpg文件生成(最终生成后存放在dists/stable目录中)
注意:本节的操作必须在Release文件生成后和密钥生成之后才可以进行,否则会出错。
调用格式为:gpg –passphrase ‘PPAPwd’ –pinentry-mode loopback –output dists/stable/Release.gpg -abs dists/stable/Release。如下:
# 生成Release.gpg文件 $ gpg --passphrase "PPAPwd" --pinentry-mode loopback --output dists/stable/Release.gpg -abs dists/stable/Release
本条命令有点复杂,可以根据参数和值的顺序来进行分析:
命令开始于gpg,表示使用gpg软件中的gpg命令;
第一个参数为–passphrase,表示密钥的密码,即在–full-generate-key一步中输入的密码,在这里密码为:PPAPwd;
第二个参数为–pinentry-mode,表示设置pinentry的模式,在这里设置为loopback,表示可以使用–passphrase所提供的密码,从而可以实现不弹出界面而输入密钥密码,使之可以用脚本在服务器端导出公钥文件;
第三个参数为–output,表示写入到文件,值为dists/stable/Release.gpg。
第四个参数为-abs,包含–armor,–detach-sign和–sign(–clear-sign)三个参数,–armor表示输出一个以ascii编码的文件,其余两个参数表示签名。值为dists/stable/Release,表示使用之前生成的Release文件。
以上参数的详细含义可以通过:man gpg > gpg帮助手册。来进行查看。
最终生成的文件内容形式如下:
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEk5EedDfs91PXpQSCKfS6vV0k7tIFAl9XJBcACgkQKfS6vV0k 7tIDJA/+JA/aE5TuSwZ3TY9jXlLZ7jN1vzmZ3kYrYf9u8YRfcuApiS8zt1gc8R8g o3qvy8Cnc2ifVJai1fnmfCNDOR3LQru6VWfNJqRiO/GHqc3IYsU2prNDJV+jXp57 d0g3nLqKeCNlWgqxzvvcDC1wsZwiwMrjXxdNQXPWYolo79udmhPlW2lfQLnQfGDE OqP5qlDPTMvO3Agd+hDvel4T9wCha1QYc97vC369lb/wUUkzVSp6arOEN8iTu3fM fGEl9O6dPCocDLaQGiSiepQiShoxDCE4d9McE2XQ2c4n1rwaYqlx6NckaM/PH8PL 1/oJNx0ocVZd4SDttYh9Ir6yRKJppOZ7hbv64+xTEKcvKNTaTvXC85NVr/6Q7d+W Peyn0wVuMfmzHcbgZ6ckwjv9GMUlKtp/TL18xuUFMxI72tzSItmpH7/2aqI5q3NR vVIy7NlDnDKjalrGsiQWOZb9jJAVacYzqN1SkDjK0Dt6WAQtRMSVq9y9fbjIBR7g MNwCAQs8wMSLPcehMrpi6Ny6om3FMeoZ4G2p4IVhPSeVUIRjowF+h7eLjASCGQpH kjzUaEgUqXvpXuZxmXT2qLJcxhiDQR9qqCDTpuo1Ps8XdcR4gjtYemSTc/3QkXlK GDGpCRdyndN/WRvqq2dhT/zkUTAZtao7ijqZFbnthNftTn5j06w= =Wk3o -----END PGP SIGNATURE-----
到此为止,一个完整的PPA仓库创建完成。此时,目录结构如下:
├── dists │ └── stable │ ├── apt.conf │ ├── Contents-amd64.gz │ ├── main │ │ └── binary-amd64 │ │ ├── Packages │ │ └── Packages.gz │ ├── Release │ └── Release.gpg ├── pool │ └── main │ ├── picoscenes-driver-20191229.deb │ ├── picoscenes-platform-2020.0816.1248-Linux.deb │ └── picoscenes-plugins-demo-rxsbroadcaster-echoprobe-20.0718.0252-Linux.deb └── project └── ppa-public-key.gpg
4.使用定制软件仓库安装软件
当搭建软件仓库成功后,在浏览器访问服务器IP或者访问对应域名,可以看见类似如图2所示内容:

这时其他用户就可以使用你定制的PPA,具体操作如下:
1.添加密钥
# 添加密钥(q后为大写英文字母O) $ wget -qO- https://服务器地址/project/ppa-public-key.gpg | sudo apt-key add - OK
显示OK即可,这时可以通过apt-key list可以查看已经信任的密钥:
# 显示信任密钥 $ apt-key list /etc/apt/trusted.gpg -------------------- ... pub rsa4096 2020-09-08 [SC] DF43 1E9A FB95 3A97 7D83 071A 7B26 77D0 4250 EA0E uid [ unknown] PPA-Demo (NO) <XX@XXX.com> sub rsa4096 2020-09-08 [E] ... /etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg ------------------------------------------------------ pub rsa4096 2012-05-11 [SC] 790B C727 7767 219C 42C8 6F93 3B4F E6AC C0B2 1F32 uid [ unknown] Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com> /etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg ------------------------------------------------------ pub rsa4096 2012-05-11 [SC] 8439 38DF 228D 22F7 B374 2BC0 D94A A3F0 EFE2 1092 uid [ unknown] Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com> ...
可以看到其中有我们在服务器端生成的密钥,这表示此时PC机信任来自这个服务器密钥生成的配置信息。在添加密钥之后便可以添加软件仓库。
2.添加软件仓库
添加软件仓库的命令add-apt-repository在软件包software-properties-common中,确保你的服务器已经安装software-properties-common,若没有安装,执行sudo apt install software-properties-common进行安装。
安装完成之后,执行如下命令添加软件仓库:
# 添加软件仓库 $ sudo add-apt-repository 'deb [arch=amd64] https://服务器地址/ stable main'
添加之后如果执行sudo apt update将会看见你的服务器地址出现在列表中,类似如下:
# 更新源 $ sudo apt update ... Ign:16 https://服务器地址 stable InRelease Get:17 https://服务器地址 stable Release [1,896 B] Get:19 https://服务器地址 stable Release.gpg [659 B] Get:20 https://服务器地址 stable/main amd64 Packages [1,690 B] ... Reading package lists... Done Building dependency tree Reading state information... Done All packages are up to date.
这表明添加密钥及软件仓库成功,此后,就可以在终端直接sudo apt install xxx来安装你定制的软件。
3.移除密钥以及软件仓库
当出于某种原因需要移除密钥和软件仓库时,可以执行如下代码:
# 移除密钥(引号中的值即为apt-key list中显示的一长串字母数字的组合) $ sudo apt-key del 'DF43 1E9A FB95 3A97 7D83 071A 7B26 77D0 4250 EA0E' OK # 移除软件仓库 sudo apt-add-repository -r 'deb [arch=amd64] https://服务器地址/ stable main'
两步都成功后,定制软件仓库完整的从本地移除,之后执行一次apt update来更新一下源仓库的配置信息即可。
对于基于ubuntu的发行版的linux机器,例如Linux mint20.04,可以在软件源(Software Sources)中进行移除软件仓库和认证密钥,如图3所示:

至此,一个完整的定制软件仓库生成,使用以及移除全部完成。