写在前面:
经过一段时间对OBS构建系统的不断失败-重装,总结了一些经验,并且有意要把许多零散的资料再汇总一下,边学习边总结,于是有了这篇文章,希望不要太长。文章中也会比较详细的对比一下obs和koji之间的区别和二者工作重心的异同。
我把一些关于obs的资料放在这里,本文的理论部分都来自于这些资料:
1. obs官方文档
2. deploy OBS
3. obs使用笔记
一、OBS简介
这里的obs指的是和之前研究的Fedora koji类似的一个用于从源码包到二进制包比如rpm的构建系统,全称是open build service.它由Linux发行版openSUSE所在社区开发,在GitHub openSUSE project开源,大家有兴趣可以进去看一看.
这是openEuler社区的obs界面,界面相比于koji可能会更加美观,特别是对于obsworker(koji里叫builder)工作情况还有图形化的总结(statisical),这样会更直观地查看worker是否负载均衡以及有没有worker“罢工”保持idle.
从功能上来看,obs比koji更加全面,obs可以为deb,rpm,tar甚至appimage打包,而koji只能打包rpm。obs不仅为openSUSE设计,后续扩展为面向多发行版、多架构、多格式的打包发布平台,更加通用,被很多Linux发行版选为官方的构建系统。
二、快速部署自己的OBS
obs的部署比起koji更简单也更难,openSUSE官方提供多种已部署好obs开箱即用的镜像供大家使用(且在本地自带obsworker),并且提供了一键部署的脚本
/usr/lib/obs/server/setup-appliance.sh --force
执行脚本后就能初始化在本地运行所有组件的obs(确信)。
但是难就难在部署过程不是很明确,一旦镜像出问题不好修,所以需要本篇文章把obs的各组件给分析一下,方便日后学习。
下面进行初体验一下,主要是知道OBS长什么样,不过这不是重点。
1. 下载已部署好obs的镜像
名称 | 下载连接 | 介绍 |
OBS Appliance Installer | https://download.opensuse.org/repositories/OBS:/Server:/2.10/images/iso/obs-server.x86_64-oem.iso | 它是完整的软件包,一个最新且稳定的 Linux 操作系统 (openSUSE Leap 15.6),捆绑了您开始使用所需的所有服务器和 OBS 组件。每次openSUSE大版本更新就会发布新ISO,只是这个ISO只能BIOS启动,不能从UEFI启动。 |
VMware Disk Image | https://download.opensuse.org/repositories/OBS:/Server:/2.10/images/obs-server.x86_64-vmdk.vmdk.xz | 为vmware虚拟机准备的开箱即用的磁盘镜像 |
VirtualBox Disk Image | https://download.opensuse.org/repositories/OBS:/Server:/2.10/images/obs-server.x86_64-vdi.vdi.xz | 为virtualbox虚拟机准备的开箱即用的磁盘镜像 |
Kvm/Qemu qcow2 Image | https://download.opensuse.org/repositories/OBS:/Server:/2.10/images/obs-server.x86_64-qcow2.qcow2 | 为kvm/qemu虚拟机准备的开箱即用的磁盘镜像 |
如果把obs部署在虚拟机里的话大家按照自己的需要选择一个就好(虚拟机镜像记得解压缩),都是直接导入进虚拟机就能使用的。我这里用ISO镜像,在Linux用qemu启动使用opensuse with obs做一个展示和记录。先使用官方镜像看看里面的组件和运行状态,然后再自己从头开始部署可能会更加明确步骤。
2. 新建虚拟机
选择openSUSE就好,硬件资源给足,磁盘可以分大一点。
把整个/dev/vda交给obs,在自动化部署交互界面直接确认就好。然后进行漫长的等待(openSUSE安装都挺慢的,可能是安装的包比较多)。
第一次启动会在这个地方卡十分钟左右,后面做好FQDN的设置进去就很快了。
官网 oem 镜像在开机时会循环10分钟检查域名.
其实从开机日志里我们也能看到其中有"OBS source service server"(源代码管理组件)、"OBS signer service"(gpg签名组件)、"OBS source repository"(源码仓库管理组件)、"OBS worker"(运行在本地的obsworker组件)、"MariaDB data server"(MySQL数据库组件)等。在自己部署的时候这些都是必备的步骤。
进入系统后此时还不能用ssh连接,先登陆然后设置sshd_config。
账号:root
密码:opensuse
官方提供的镜像会把所有需要的包都安装好,基本上不用自己用zypper了。
vim /etc/ssh/sshd_confg
# 保持如下设置
Port 22
PermitRootLogin yes
PasswordAuthentication yes
PermitEmptyPasswords no
systemctl restart sshd
这时候就可以用ssh访问了,不需要禁用selinux.
3. 设置FQDN
由于osc命令在通过API访问obs后端的时候是需要一个url的,这个url不可以是一个ip地址,所以需要给它设定一个FQDN(你可以认为是本地域名),通过这个“域名”来访问obs后端。
vim /etc/hostname
# 填入你要设定的本机hostname
april
---
vim /etc/hosts
# 填入你要做的ip -> 本地域名映射
192.168.122.91 obs.april.com april
---
# 通过hostname -F更新FQDN
localhost:~ # hostname -F /etc/hostname
localhost:~ # hostname -f
obs.april.com
localhost:~ # hostname
april
我部署的koji的本地域名是koji.april.com,obs这里我就设置为obs.april.com了,这里的域名可以随便写,也可以写成build.opensuse.org(确信)。设置好之后重启一下看启动时间是否变短了,至少要退出当前root用户再重新登陆一下更新hostname设置。现在我重启只需要不到1分钟了。
重启后就显示了当前的web和api接口,就是上面设置的FQDN本地域名。
4. 外部访问obs
由于部署好的obs所在opensuse系统是没有图形界面的,所以需要在宿主机通过本地域名来访问obs前端。
sudo vim /etc/hosts
192.168.122.59 koji.april.com
192.168.122.91 obs.april.com
然后就能通过在浏览器访问https://obs.april.com的方式访问obs了。注意在部署的时候已经自动进行SSL证书签名了(属于本地自签),可以通过https,443端口访问的。
信任一下自签证书然后“接受风险并继续就好”。
然后访问obs的前端界面。
账号:Admin
密码:opensuse
5. 观察统计信息
当前系统有几个逻辑核心,初始化的时候就会创建几个本地obsworker。此时运行着一些服务。
systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
apache2.service loaded active running The Apache Webserver
boot-sysctl.service loaded active exited Apply Kernel Variables for 6.4.0-150600.23.42-default from /boot
dbus.service loaded active running D-Bus System Message Bus
detect-part-label-duplicates.service loaded active exited Detect if the system suffers from bsc#1089761
dracut-shutdown.service loaded active exited Restore /run/initramfs on shutdown
getty@tty1.service loaded active running Getty on tty1
kbdsettings.service loaded active exited Apply settings from /etc/sysconfig/keyboard
klog.service loaded active exited Early Kernel Boot Messages
kmod-static-nodes.service loaded active exited Create List of Static Device Nodes
lvm2-monitor.service loaded active exited Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
mariadb.service loaded active running MariaDB database server
memcached.service loaded active running memcached daemon
obs-clockwork.service loaded active running Open Build Service Clockwork Daemon
obs-delayedjob-queue-consistency_check.service loaded active running Open Build Service DelayedJob Queue: consistency_check
obs-delayedjob-queue-default.service loaded active running Open Build Service DelayedJob Queue: default
obs-delayedjob-queue-issuetracking.service loaded active running Open Build Service DelayedJob Queue: issuetracking
obs-delayedjob-queue-mailers.service loaded active running Open Build Service DelayedJob Queue: mailers
obs-delayedjob-queue-project_log_rotate.service loaded active running Open Build Service DelayedJob Queue: project_log_rotate
obs-delayedjob-queue-quick@0.service loaded active running Open Build Service DelayedJob Queue Instance: quick
obs-delayedjob-queue-quick@1.service loaded active running Open Build Service DelayedJob Queue Instance: quick
obs-delayedjob-queue-quick@2.service loaded active running Open Build Service DelayedJob Queue Instance: quick
obs-delayedjob-queue-releasetracking.service loaded active running Open Build Service DelayedJob Queue: releasetracking
obs-delayedjob-queue-staging.service loaded active running Open Build Service DelayedJob Queue: staging
obs-sphinx.service loaded active running Open Build Service Sphinx Search Daemon
obsdeltastore.service loaded active running OBS deltastore daemon
obsdispatcher.service loaded active running OBS job dispatcher daemon
obsdodup.service loaded active running OBS dodup, updates download on demand metadata
obspublisher.service loaded active running OBS repository publisher
obsrepserver.service loaded active running OBS repository server
lvm2-monitor.service loaded active exited Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
mariadb.service loaded active running MariaDB database server
memcached.service loaded active running memcached daemon
obs-clockwork.service loaded active running Open Build Service Clockwork Daemon
obs-delayedjob-queue-consistency_check.service loaded active running Open Build Service DelayedJob Queue: consistency_check
obs-delayedjob-queue-default.service loaded active running Open Build Service DelayedJob Queue: default
obs-delayedjob-queue-issuetracking.service loaded active running Open Build Service DelayedJob Queue: issuetracking
obs-delayedjob-queue-mailers.service loaded active running Open Build Service DelayedJob Queue: mailers
obs-delayedjob-queue-project_log_rotate.service loaded active running Open Build Service DelayedJob Queue: project_log_rotate
obs-delayedjob-queue-quick@0.service loaded active running Open Build Service DelayedJob Queue Instance: quick
obs-delayedjob-queue-quick@1.service loaded active running Open Build Service DelayedJob Queue Instance: quick
obs-delayedjob-queue-quick@2.service loaded active running Open Build Service DelayedJob Queue Instance: quick
obs-delayedjob-queue-releasetracking.service loaded active running Open Build Service DelayedJob Queue: releasetracking
obs-delayedjob-queue-staging.service loaded active running Open Build Service DelayedJob Queue: staging
obs-sphinx.service loaded active running Open Build Service Sphinx Search Daemon
obsdeltastore.service loaded active running OBS deltastore daemon
obsdispatcher.service loaded active running OBS job dispatcher daemon
obsdodup.service loaded active running OBS dodup, updates download on demand metadata
obspublisher.service loaded active running OBS repository publisher
obsrepserver.service loaded active running OBS repository server
obsscheduler.service loaded active exited OBS job scheduler
obsservice.service loaded active running OBS source service server
obsservicedispatch.service loaded active running OBS source service dispatcher
obssignd.service loaded active running GPG Sign Daemon
obssigner.service loaded active running OBS signer service
obssrcserver.service loaded active running OBS source repository server
obsstoragesetup.service loaded active exited OBS storage setup
obswarden.service loaded active running OBS warden, monitors the workers
obsworker.service loaded active exited OBS worker
rng-tools.service loaded active running Start the rngd daemon
rsyslog.service loaded active running System Logging Service
serial-getty@ttyS0.service loaded active running Serial Getty on ttyS0
slpd.service loaded active running OpenSLP daemon for the Service Location Protocol
sshd.service loaded active running OpenSSH Daemon
systemd-binfmt.service loaded active exited Set Up Additional Binary Formats
其中以obs开头的就是obs的组件了,我们通过官方文档看看它们分别起到什么作用。
1. obssrcserver
源代码服务。维护源存储库和项目/包配置。它提供 HTTP 接口,这是与前端的唯一接口。它可以将请求转发到其他后端服务。每个 OBS 安装都只有一个源服务器。它维护“sources”、“trees”和“projects”。
2.obsrepserver
软件源服务。repository server通过 HTTP 接口提供对二进制文件的访问。它仅由前端通过obssrcserver使用。obsworker使用服务器进行注册、请求构建作业所需的二进制文件并存储结果。obsrepserver还会创建调度程序的通知。每个 OBS 安装至少有一个repository server。在每个比较重要的机器上都有一个obsrepserver。
3. obsscheduler
调度程序计算构建作业的需求。它检测源、项目配置或构建环境中使用的二进制文件中的变化。它负责以正确的顺序启动作业并集成构建的二进制包。每个 OBS 安装针对每个可用架构都有一个调度程序。
如图所示,当前支持架构都有一个bs_sched在运行,目前还没有添加risc-v架构进来。
4. obsdispatcher
调度程序接收作业(由调度程序创建)并将其分配给空闲的worker。它还会检查可能的构建约束,以验证worker是否有资格执行该作业。它只会通知worker有关作业的信息;worker本身会下载所需的资源。每个 OBS 都有一个调度程序(其中一个是主调度程序)。
5. obspublisher
obspublisher处理来自已完成存储库的调度程序的“publish”事件。它将所有架构的构建结果合并到定义的目录结构中,创建所需的metadata,并把软件包推送到下载服务器。它在后端维护“repos”目录.
6. obsworker
工作者在obsrepserver上注册。它们从dispatcher程序接收构建作业。然后,它们从source server下载源文件,并从repository server(s)下载所需的二进制文件。它们使用构建脚本构建包并将结果发送回repository server.。worker可以与其他OBS服务在同一台主机上运行(默认),但正常来说obsworker会跑在对应架构的构建机上。
7. obssigner
signer处理签名事件并调用外部工具来执行签名,比如gpgcheck。
8. obswarden
Warden 监控 worker 并检测崩溃或挂起的 worker。崩溃的worker的构建作业将被取消,然后在另一台构建机上重新启动。
9. obsdodup
按需下载软件包。就是说构建软件包的工具链toolchain(比如gcc,make,cmake等)如果不在本地存在的话,需要去meta中配置好的repo中下载
使用DoD的目的:
- 节省磁盘空间: 仅下载所需的软件包
- 自动包更新: 在上游更改时获取更新
- 简单配置: 可在项目 meta 中配置
10. obsdeltastore
obsdeltastore维护源存储中的增量。多个 obscpio 档案可以存储在一个增量存储中,以避免磁盘上出现重复。此服务计算增量并维护增量存储。
从上述例子中可以看出obs的各组件主要使用perl编程语言,service启动组件的模板是
/usr/bin/perl -w /usr/lib/obs/server/bs_warden --logfile warden.log
obs各组件的源代码放置在/usr/lib/obs/server/目录下,日志存放在/srv/obs/log/这个目录下。
配置oscrc使其能访问obs后端,osc是obs的一个命令行工具,类似koji是kojihub的命令行工具,实际上命令行工具应该是比图形前端更加重要,能够做更多设置,现在来配置一下。
vim ~/.config/osc/oscrc
# 填入以下内容
[general]
apiurl=https://obs.april.com
[https://obs.april.com]
user=Admin
pass=opensuse
credentials_mgr_class=osc.credentials.PlaintextConfigFileCredentialsManager
使用osc list查看当前有哪些project工程.我当前创建了三个。
以上是直接使用openSUSE提供的镜像,虽然开箱即用但是部署在实体机上拿来用可能不太合适,所以下面进行脚本部署OBS。
三、部署本地OBS
april:~ # /usr/lib/obs/server/setup-appliance.sh --force
Starting setup-appliance.sh at Thu Mar 27 09:43:44 CST 2025
Generating OBS default GPG key ....gpg: keybox '/srv/obs/gnupg/pubring.kbx' created
gpg: Generating a default OBS instance key
gpg: /srv/obs/gnupg/trustdb.gpg: trustdb created
gpg: directory '/srv/obs/gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/srv/obs/gnupg/openpgp-revocs.d/869C3A70EA9491D107AB911BA0DCFE228F75A20C.rev'
gpg: done
done
~ ~
/usr/lib/obs/server/setup-appliance.sh: line 656: ./obssrcserver: No such file or directory
/usr/lib/obs/server/setup-appliance.sh: line 657: ./obsrepserver: No such file or directory
~
Created symlink /etc/systemd/system/multi-user.target.wants/obsrepserver.service -> /usr/lib/systemd/system/obsrepserver.service.
Created symlink /etc/systemd/system/multi-user.target.wants/obssrcserver.service -> /usr/lib/systemd/system/obssrcserver.service.
Created symlink /etc/systemd/system/multi-user.target.wants/obsscheduler.service -> /usr/lib/systemd/system/obsscheduler.service.
Created symlink /etc/systemd/system/multi-user.target.wants/obsdispatcher.service -> /usr/lib/systemd/system/obsdispatcher.service.
Created symlink /etc/systemd/system/multi-user.target.wants/obspublisher.service -> /usr/lib/systemd/system/obspublisher.service.
obsdodup: unknown service
Service obsdodup is not enabled. Would you like to enable it? [Yn]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsdodup.service -> /usr/lib/systemd/system/obsdodup.service.
obsdeltastore: unknown service
Service obsdeltastore is not enabled. Would you like to enable it? [Yn]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsdeltastore.service -> /usr/lib/systemd/system/obsdeltastore.service.
obssigner: unknown service
Service obssigner is not enabled. Would you like to enable it? [Yn]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obssigner.service -> /usr/lib/systemd/system/obssigner.service.
obssignd: unknown service
Service obssignd is not enabled. Would you like to enable it? [Yn]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obssignd.service -> /usr/lib/systemd/system/obssignd.service.
obsservicedispatch: unknown service
Service obsservicedispatch is not enabled. Would you like to enable it? [Yn]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsservicedispatch.service -> /usr/lib/systemd/system/obsservicedispatch.service.
obswarden: unknown service
Service obswarden is not enabled. Would you like to enable it? [yN]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obswarden.service -> /usr/lib/systemd/system/obswarden.service.
obsapisetup: unknown service
Service obsapisetup is not enabled. Would you like to enable it? [yN]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsapisetup.service -> /usr/lib/systemd/system/obsapisetup.service.
obsstoragesetup: unknown service
Service obsstoragesetup is not enabled. Would you like to enable it? [yN]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsstoragesetup.service -> /usr/lib/systemd/system/obsstoragesetup.service.
obsworker: unknown service
Service obsworker is not enabled. Would you like to enable it? [yN]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsworker.service -> /usr/lib/systemd/system/obsworker.service.
obsservice: unknown service
Service obsservice is not enabled. Would you like to enable it? [yN]
Default: y
Created symlink /etc/systemd/system/multi-user.target.wants/obsservice.service -> /usr/lib/systemd/system/obsservice.service.
Checking unit mysql.service ...
Enabling mysql.service
mysql.service daemon not started. Trying to start
Waiting for FQHOSTNAME (599)
Appliance hostname changed from NOTHING to obs.april.com !
Adapting present worker jobs
Adjust configuration for this hostname
Initialize MySQL databases (first time only)
- reconfiguring /etc/my.cnf
- installing to new datadir
Installing MariaDB/MySQL system tables in '/srv/obs/MySQL' ...
OK
To start mariadbd at boot time you have to copy
support-files/mariadb.service to the right place for your system
Two all-privilege accounts were created.
One is root@localhost, it has no password, but you need to
be system 'root' user to connect. Use, for example, sudo mysql
The second is root@localhost, it has no password either, but
you need to be the system 'root' user to connect.
After connecting you can set the password, if you would need to be
able to connect as any of these users with a password and without sudo
See the MariaDB Knowledgebase at https://mariadb.com/kb
You can start the MariaDB daemon with:
cd '/usr' ; /usr/bin/mariadbd-safe --datadir='/srv/obs/MySQL'
You can test the MariaDB daemon with mysql-test-run.pl
cd '/usr/share/mysql-test' ; perl mariadb-test-run.pl
Please report any problems at https://mariadb.org/jira
The latest information about MariaDB is available at https://mariadb.org/.
Consider joining MariaDB's strong and vibrant community:
https://mariadb.org/get-involved/
- changing ownership for new datadir
- restarting mysql
- setting new password for user root in mysql
Initialize OBS api database (first time only)
Setting ownership of '/srv/obs' obsrun
Setting up rails environment
- Doing 'rails db:create'
- Doing 'rails db:setup'
- Doing 'rails writeconfiguration'
Proposed DNS names:
Default: obs obs.april.com localhost
Creating a default SSL certificate for the server
Please replace it with your version in /srv/obs/certs directory...
Creating crt/key in /srv/obs/certs
update-alternatives: using /usr/bin/rake.ruby.ruby2.7 to provide /usr/bin/rake (rake) in manual mode
Checking unit apache2.service ...
Enabling apache2.service
apache2.service daemon not started. Trying to start
Checking unit memcached.service ...
Enabling memcached.service
memcached.service daemon not started. Trying to start
Checking unit obs-api-support.target ...
Enabling obs-api-support.target
obs-api-support.target daemon not started. Trying to start
Recreating /etc/issue
Creating overview.html