按需构建服务
项目描述
按需构建服务 - ODCS
什么是ODCS
ODCS的主要目标是允许使用REST API调用生成临时构建。我们主要指的是包含从不同来源获取的软件包的RPM软件包库,但未来也可能生成其他输出类型。
ODCS可以从多个来源获取构建的RPM,如Koji标签、在Koji中构建的模块或由Pulp工具提供的第三方库。
使用ODCS客户端库
存在一个用Python编写的客户端库,它允许轻松访问由ODCS服务器提供的REST API。
安装ODCS客户端
在Fedora上
$ sudo dnf install odcs-client
如果您想使用pip
进行安装,可以运行以下命令
$ sudo pip install odcs[client]
如果您想使您的Python项目依赖于ODCS客户端库并将其添加到requirements.txt
中,您只需使用以下命令即可依赖ODCS客户端
odcs[client]
ODCS认证系统
ODCS服务器可以被配置为使用OpenIDC、Kerberos或SSL进行认证。最终,它可以设置为无认证模式以支持匿名访问。根据ODCS服务器的配置,您必须在创建ODCS类实例时设置您的认证方法。
使用OpenIDC进行认证
要使用OpenIDC,您必须向ODCS客户端类构造函数提供OpenIDC令牌。要获取该OpenIDC令牌,您可以使用python-openidc-client
库,或者要求OpenIDC提供者提供服务令牌,该令牌无需刷新。一旦您有了令牌,您就可以创建ODCS实例,如下所示
from odcs.client.odcs import ODCS, AuthMech
odcs = ODCS("https://odcs.fedoraproject.org",
auth_mech=AuthMech.OpenIDC,
openidc_token="your_openidc_token")
使用python-openidc-client
库获取openidc_token
的方法如下
import openidc_client
staging = False
if staging:
id_provider = 'https://id.stg.fedoraproject.org/openidc/'
else:
id_provider = 'https://id.fedoraproject.org/openidc/'
# Get the auth token using the OpenID client.
oidc = openidc_client.OpenIDCClient(
'odcs',
id_provider,
{'Token': 'Token', 'Authorization': 'Authorization'},
'odcs-authorizer',
'notsecret',
)
scopes = [
'openid',
'https://id.fedoraproject.org/scope/groups',
'https://pagure.io/odcs/new-compose',
'https://pagure.io/odcs/renew-compose',
'https://pagure.io/odcs/delete-compose',
]
try:
token = oidc.get_token(scopes, new_token=True)
token = oidc.report_token_issue()
except requests.exceptions.HTTPError as e:
print(e.response.text)
raise
使用Kerberos进行认证
要使用Kerberos,您必须有有效的Kerberos票据或您需要拥有Kerberos密钥表文件。如果您想使用带有Kerberos密钥表的ODCS客户端库,您必须将环境变量KRB5_CLIENT_KTNAME
设置为要使用的密钥表的完整路径。例如,您可以这样做
from odcs.client.odcs import ODCS, AuthMech
from os import environ
environ["KRB5_CLIENT_KTNAME"] = "/full/path/to/ketab"
odcs = ODCS("https://odcs.fedoraproject.org",
auth_mech=AuthMech.Kerberos)
使用SSL进行认证
要使用SSL,您必须拥有SSL客户端证书和密钥文件。然后,您必须选择SSL AuthMech并传递SSL客户端证书和密钥的路径,如下所示
from odcs.client.odcs import ODCS, AuthMech
odcs = ODCS("https://odcs.fedoraproject.org",
auth_mech=AuthMech.SSL,
ssl_cert="/path/to/ssl-crt.pem",
ssl_key="/path/to/ssl-key.pem")
请求新的组合
请求新的ODCS组合的一般方法如下
compose = odcs.new_compose(sources, source_type)
sources
和source_type
都是字符串。根据source_type
的值,sources
具有以下含义
source_type |
source |
---|---|
tag | 从RPMs中获取Koji标签的名称。 |
module | 用空格分隔的NAME:STREAM或NAME:STREAM:VERSION的模块,这些模块将包含在组合中。 |
pulp | 用空格分隔的内容集或存储库ID列表。存储库将被包含在组合中。 |
raw_config | 具有name#commit 哈希格式的字符串。name 必须与ODCS服务器配置中定义的raw_config_urls 作为raw config位置之一匹配。commit 是定义要使用的raw config版本的commit哈希。然后,此配置用作Pungi的输入配置。此配置将用作Pungi的输入配置。 |
build | 在请求中省略源。组合中包含的Koji构建列表由builds 属性定义。 |
pungi_compose | 指向由Pungi生成的外部组合的变体存储库的URL。例如 https://kojipkgs.fedoraproject.org/compose/rawhide/latest-Fedora-Rawhide/compose/Server/。生成的组合将包含与给定外部组合变体相同的RPM集。包将来自配置的Koji实例。 |
您还可以将一些附加的可选属性传递给new_compose(...)
方法
seconds_to_live
- 在生成组合后多少秒应该过期并被删除。packages
- 应包含在组合中的包的列表。这仅在source_type
设置为tag
或build
时使用,以进一步限制组合存储库。如果未设置packages
,则将包括Koji标签中的所有包或在builds
列表中的所有包。flags
- 进一步修改组合输出的标志列表no_deps
- 对于tag
source_type
,不解析包之间的依赖关系,只包含在 compose 中列出的packages
。对于module
source_type
,不解析模块之间的依赖关系,只包含请求的模块在 compose 中。include_unpublished_pulp_repos
- 对于pulp
source_type
,还包括输入内容集的未发布仓库。check_deps
- 当设置时,如果某个包有损坏的依赖关系,则中止 compose。no_reuse
- 当设置时,不要尝试重用旧的 compose。ignore_absent_pulp_repos
- 对于pulp
source_type
,忽略任何不存在于 Pulp 中的内容集。use_only_compatible_arch
- 仅适用于pulp
source_type
。当此标志设置时,从 Pulp 返回的 URL 中硬编码的体系结构将被替换为$basearch
变量。仓库定义也将定义skip_if_unavailable = 1
。当 repofile 中包含多个内容集以完全忽略不兼容架构的仓库中的包时,这可能很有用。
sigkeys
- 签名密钥 ID 的列表。只有由这些密钥之一签名的包才会包含在 compose 中。如果没有包的签名版本,则 compose 将失败。也可以在列表中传递空字符串,表示允许未签名的包。例如,如果您想首选由 ID 为123
的密钥签名的包,并且还允许未签名的包出现在 compose 中,您可以通过将 sigkeys 设置为["123", ""]
来实现。results
- 将作为 compose 生成的一部分生成附加结果的列表。有效的键是iso
- 从 compose 生成不可安装的 ISO 文件,包含 RPM。boot.iso
- 生成images/boot.iso
文件,该文件是构建基于结果的容器镜像所需的。
arches
- 构建此 compose 的附加 Koji 架构的列表。默认情况下,compose 仅针对 "x86_64" 架构构建。multilib_arches
- 应启用多体系的arches
的子集。对于multilib_arches
列表中的每个体系结构,ODCS 将包括在 compose 中的其他兼容体系结构的包。例如,当 "x86_64" 包含在multilib_arches
中时,ODCS 将包括 "i686" 包。包含在 composes 中的包的集合受到multilib_method
列表的影响。multilib_method
- 定义用于确定是否将包视为多体系的方法的列表。默认为空列表。该列表可以有以下值iso
- 从 compose 生成不可安装的 ISO 文件,包含 RPM。runtime
- 名称以 "-devel" 或 "-static" 后缀结尾的包将被视为多体系。devel
- 安装某些共享对象文件 ".so." 的包将被视为多体系。all
- 所有包都将被视为多体系。
builds
- 定义要在 compose 中包含的 Koji 构建的 NVR 列表。仅适用于tag
和build
source 类型。对于tag
source 类型,NVRs 将在source
定义的 Koji 标签之上考虑包含在 compose 中。对于build
source 类型,仅考虑由 NVR 定义的 Koji 构建。仍然需要设置packages
以包含 compose 中的特定 Koji 构建。lookaside_repos
- 指向包含将被内部依赖关系解析器用于解析依赖关系的包的 RPM 仓库的 URL 列表。来自这些仓库的包将不会出现在结果 ODCS compose 中,但在check_deps
ODCS 标志检查 RPM 依赖关系是否在结果 compose 中满足时,将考虑这些包。module_defaults_url
- 包含模块默认数据 Git 仓库的 URL 和分支名或提交哈希值的列表。例如 ["https://pagure.io/releng/fedora-module-defaults.git", "master"]。这仅在创建包含非模块 RPM 的模块化 compose 时使用。modular_koji_tags
- 包含模块 Koji 内容生成器构建的 Koji 标签的列表。这些构建将被包含在 compose 中。
new_compose
方法返回描述 compose 的 dict
对象,例如
{
"arches": "x86_64 ppc64",
"flags": [
"no_deps"
],
"id": 1,
"owner": "jkaluza",
"packages": "gofer-package",
"removed_by": null,
"result_repo": "https://odcs.fedoraproject.org/composes/latest-odcs-1-1/compose/Temporary",
"result_repofile": "https://odcs.fedoraproject.org/composes/latest-odcs-1-1/compose/Temporary/odcs-1.repo",
"results": [
"repository"
],
"sigkeys": "",
"source": "f26",
"source_type": 1,
"state": 3,
"state_name": "wait",
"time_done": "2017-10-13T17:03:13Z",
"time_removed": "2017-10-14T17:00:00Z",
"time_submitted": "2017-10-13T16:59:51Z",
"time_to_expire": "2017-10-14T16:59:51Z"
}
其中最有用的数据是 result_repofile
,它指向包含生成的 compose 的 URL 的 .repo 文件。另一个非常重要的数据是 state
和 state_name
字段。一个 compose 有以下状态
state |
state_name |
描述 |
---|---|---|
0 | wait | Compose 正在队列中等待生成 |
1 | generating | Compose 正在生成 |
2 | done | Compose 已生成 - 完成 |
3 | removed | Compose 已过期并被删除 |
4 | failed | Compose 生成失败 |
正如您在示例中看到的那样,compose 处于 wait
状态,因此我们必须等待 ODCS 生成 compose。
等待 compose 生成
有两种方法可以等待 compose 生成。首选的方法是监听 Fedora 消息总线上的 odcs.state.change
消息,带有 done
或 failed
状态,另一种方法是使用 wait_for_compose(...)
方法实现的 HTTP 轮询。
如果您的应用程序由于某些原因不允许监听总线,您可以使用 wait_for_compose(...)
方法如下
compose = odcs.new_compose(sources, source_type)
# Blocks until the compose is ready, but maximally for 600 seconds.
compose = odcs.wait_for_compose(compose["id"], timeout=600)
if compose["state_name"] == "done":
print "Compose done, URL with repo file", compose["result_repofile"]
else:
print "Failed to generate compose"
检查现有 ODCS compose 的状态
一旦您有了 ready 的 compose,您可能想稍后检查其状态。这可以通过使用 get_compose(...)
方法实现,如下所示
compose = odcs.get_compose(compose["id"])
续订 compose
如果您的 compose 的 time_to_expire
即将到期,并且您知道您想继续使用该 compose,您可以使用 renew_compose(...)
方法增加 time_to_expire
。您还可以使用此方法在 removed
状态下重新生成过期的 compose。这样的 compose 将具有与原始 compose 相同的软件包版本。
compose = odcs.renew_compose(compose["id"])
开发
代码约定
代码必须通过 black
进行良好格式化并通过 flake8
检查。
运行 tox -e black,flake8
进行检查。
单元测试
安装编译一些 Python 软件包所需的 pip 包
$ sudo dnf install -y gcc swig redhat-rpm-config python-devel openssl-devel openldap-devel \
zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel tk-devel \
git python3-cairo-devel cairo-gobject-devel gobject-introspection-devel
许多这些依赖项来自模块 pygobject。
运行测试
$ make check
测试来自纯 RPM 仓库的本地 compose
您可以通过使用以下命令从 ./server/tests/repo
仓库生成 compose 来测试 ODCS
$ ./create_sqlite_db
$ ./start_odcs_from_here
在执行 start_odcs_from_here
命令之前,需要运行支持 AMQP 协议的消息代理以本地运行异步任务以生成 compose。以下是一个运行 RabbitMQ 代理的示例
sudo dnf install -y rabbitmq-server
sudo systemctl start rabbitmq-server
将 repo
源类型添加到服务器配置 ./server/odcs/server/config.py
中。(这将导致一些测试失败,因此您在完成更改后需要将其回滚!)
然后在另一个终端中提交请求到前端
$ ./submit_test_compose repo `pwd`/server/tests/repo ed
{
"id": 1,
"owner": "Unknown",
"result_repo": null,
"source": "/home/hanzz/code/fedora-modularization/odcs/tests/repo",
"source_type": 3,
"state": 0,
"state_name": "wait",
"time_done": null,
"time_removed": null,
"time_submitted": "2017-06-12T14:18:19Z"
}
然后您应该看到后端进程正在生成 compose,一旦完成,生成的 compose 将在 ./test_composes/latest-Unknown-1/compose/Temporary
目录中。
使用 docker-compose 创建本地设置
您可以使用 docker-compose 文件创建 ODCS 的测试设置。此 yaml 文件为 ODCS 的后端和前端设置创建 docker 容器,并一起运行多个服务。这些服务是;
- rabbitmq(处理后端和前端之间的通信)
- postgres (创建存储本地生成composes的数据库)
- backend (ODCS的后端服务)
- frontend (处理REST API的ODCS前端服务)
- static (Apache服务,用于提供存储)
- beat (后端Cronjob,用于检查服务状态)
除此之外,还创建了三个docker卷(odcs_odcs-composes
,odcs_odcs-postgres
和odcs_rabbitmq
)。这些卷为服务提供持久存储。
此yaml文件还需要一个.env
文件,该文件指定了前端和后端配置的一些环境变量。这样的.env
文件应与docker-compose.yml
文件在同一路径,以下是需要在此文件中指定的必要变量:
# Pyhton path
PYTHONPATH=/src/common:/src/server:/src/client
# POSTGRES
POSTGRES_USER=odcs
POSTGRES_PASSWORD=password
# PULP CONFIGURATION
PULP_SERVER_URL=<URL of the pulp server>
PULP_USERNAME=<Username for the pulp server>
PULP_PASSWORD=<Credentials for the pulp server>
RAW_CONFIG_URLS=<Raw config settings in JSON format>
# ODCS CONFIGURATION
ODCS_CONFIG_SECTION=DevConfiguration
ODCS_CONFIG_DIR=/src/server/conf/
ODCS_CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672/
ODCS_DB_URL=postgresql+psycopg2://odcs:password@postgres/odcs
# Directory where the generated composes are stored. This hast to match
# location where odcs-composes volume is mounted in frontend and backend
# containers.
ODCS_TARGET_DIR=/mnt/odcs
TARGET_DIR_URL=http://localhost:8080
# FLASK SETTINGS
# Force flask to reload application on change of source files.
FLASK_ENV=development
可以使用sudo docker-compose up
命令启动服务。如果您遇到了错误或某些东西运行不正确,请按照以下步骤操作;
-
检查是否已创建docker卷。
$ sudo docker volume ls Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. DRIVER VOLUME NAME
如果输出如下,则表示还没有任何卷,运行
sudo docker-compose up
和然后运行sudo docker-compose down
命令就足够了。这将创建卷,如果再次运行上述命令,输出将如下所示;$ sudo docker volume ls Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. DRIVER VOLUME NAME local odcs_odcs-composes local odcs_odcs-postgres local odcs_odcs-rabbitmq
-
在此之后,我们需要为
ocds_odcs-composes
卷设置正确的权限。为了找到卷的实际位置,请键入以下内容$ sudo docker volume inspect odcs_odcs-composes Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. [ { "Name": "odcs_odcs-composes", "Driver": "local", "Mountpoint": "/var/lib/containers/storage/volumes/odcs_odcs-composes/_data", "CreatedAt": "2021-10-04T13:19:36.478636851+02:00", "Labels": { "io.podman.compose.project": "odcs" }, "Scope": "local", "Options": {} } ]
"Mountpoint": "/var/lib/containers/storage/volumes/odcs_odcs-composes/_data"
显示了相应卷的确切位置。通过以下方式为挂载点添加组写权限
$ sudo chmod 775 /var/lib/containers/storage/volumes/odcs_odcs-composes/_data
-
在此步骤中,运行
sudo docker-compose up
命令即可正确启动服务。
以下是用于检查ODCS的一些REST调用。
$ curl -s http://localhost:5000/api/1/composes/ | jq .
此调用显示数据库中的所有composes。$ odcs --server http://localhost:5000/ create-pulp <Pulp内容集>
此调用启动与给定的Pulp内容集匹配的Pulp composes$ odcs --server http://localhost:5000/ create-raw-config --compose-type test my_raw_config master
此调用启动一个配置为my_raw_config的composes
项目详情
odcs-0.8.1.tar.gz 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | bf91cd84a43d63c556c56ac18183ebf3d3bfd463b86567831deb642da26c3502 |
|
MD5 | ffd645f4211b306db6d21fa010b9832c |
|
BLAKE2b-256 | ba646dd5736ccb1c19eff202d1917780d4a9136d5847c11c52f5a37de02c8d3c |