openSUSE:构建服务技巧和窍门

跳转到:导航搜索

本操作指南列出了一些使用构建服务的小技巧和窍门,这些技巧和窍门没有经过分类。其中大部分应该包含在其他页面中并从这里删除。本页面的目的是为收集需要更多文档或应尽快修复的信息提供一个最初的场所。

大部分信息收集自 构建服务邮件列表 (存档)。

禁用软件包构建

有几种方法可以禁用单个软件包的构建。一种方法是使用“osc”命令行客户端。只需使用

osc api -X POST "/source/PROJECT/PACKAGE?cmd=set_flag&flag=build&status=disable" # and later
osc api -X POST "/source/PROJECT/PACKAGE?cmd=set_flag&flag=build&status=enable" # or better
osc api -X POST "/source/PROJECT/PACKAGE?cmd=remove_flag&flag=build"

或使用以下命令编辑XML

osc meta pkg -e <project> <package>

并在包的元数据中,在<build>标签内添加<disable>标签。您可以选择使用

<!-- [...] -->
<build>
  <disable arch="<build-arch>"/>
</build>
<!-- [...] -->

<!-- [...] -->
<build>
  <disable repository="<name-of-build-repository>"/>
</build>
<!-- [...] -->

或两者都用,例如

<!-- [...] -->
<build>
  <disable repository="SLES_9" arch="x86_64"/>
</build>
<!-- [...] -->

另一种方法是使用 网页客户端 并在显示相关软件包时单击相应的按钮。

注意: 已经启动的任务不会停止。要永久删除它们,您需要在本地OBS上的目录中删除它们/srv/obs/jobs/中止当前正在构建的软件包

中止当前正在构建的软件包

osc abortbuild <project> <package> <repo> <arch>

扩展错误

如果您收到类似以下的错误

expansion error have choice for inet-daemon needed by imap: inetd xinetd

对于一个软件包,您有两种选择

  • 快速修复是添加上述软件包之一(inetd 或 xinetd)到您的 BuildRequires 中
  • 另一种修复方法是在您的项目配置中设置偏好:osc meta -e prjconf 并添加一行:Prefer: xinetd
  • 长期修复是向 opensuse-buildservice 邮件列表 发送邮件,请求将其中一个文件添加到存储库的 .dsc 文件中,以便自动修复具有相同问题的其他软件包。

在项目中查找软件包

有时您可能想知道软件包的名称,尤其是在基本项目中,以便在 BuildRequires 行中使用它。有一个巧妙的 osc 调用可以找出这一点。

此命令

 osc ls -b -r standard -a i586 Fedora:20

列出 Fedora 20 中的所有二进制软件包。从输出中选择软件包名称。

请参阅

 osc ls --help 

了解更多详细信息。

仅通过本地构建构建32位rpm

然后您可以在 x84_64 机器上本地构建一个 32 位软件包,尝试

osc build <TARGET> i586

您还可以创建i586二进制文件,这些文件可以通过带有-32bit后缀的x86_64安装。为了使其工作,您需要将baselibs.conf(解释如下)添加到您的项目中。然后将参数--baselibs添加到您的osc构建命令中。

osc build --baselibs <TARGET> i586

这还应该在您的 RPMS/ 目录中本地生成 -32bit 软件包,无需 OBS 的帮助。

权限拒绝错误

如果您的软件包在本地构建时没有任何问题,但您收到类似以下的错误消息

 /usr/bin/install: cannot create regular file `/usr/lib/libfoo.so.0.0`: Permission denied

当您尝试在构建服务中构建相同的软件包时,请记住构建服务目前只支持在chroot环境中构建(您的软件包目前似乎没有使用DESTDIR或RPM_BUILD_ROOT)。

只需添加一行

# norootforbuild

到您的spec文件,您将在本地构建环境中看到相同的(顺便说一句:丑陋的)失败:在提交到构建服务之前,请先修复这些错误...

_link_aggregate

_link_aggregate 的区别

为了避免重新构建那些仅作为其他软件包的构建需求,或者仅因为项目希望为最终用户分发完整的软件包集而需要的软件包,构建服务中存在 _aggregate 功能。

通过聚合“链接”到新项目中的软件包不会在新项目中重新构建,并且原始项目中的二进制文件将在它们更改时在新项目中更新。

以下是关于 _link 或 _aggregate 的优缺点

理由 _link _aggregate 评论
无需更改源代码。   X 聚合是可行的,但会减慢您的构建速度并需要双倍空间。最好直接针对其他存储库进行构建。
我的项目需要对源代码进行一些更改。 X    
原始软件包无法在所有需要的发行版或架构上构建。 X X 最好的方法是拥有两个不同的伪包:一个使用 _aggregate 函数始终只从原始项目获取二进制包,另一个使用 _link 函数为其余部分构建包。(但最简单的方法当然是请原始维护者在他的项目中启用缺少的发行版/架构。)

请确保不要混淆链接与项目链接,后者是构建服务的附加功能。它在项目链接页面上进行了描述。

链接示例

简单 _link 示例

在您的项目中创建一个新包(名称可以与原始包相同——但这并非必不可少),并添加一个名为 _link 的文件,内容如下

<link project='openSUSE:Factory' package='tse3'/>

链接到另一个OBS实例

如果您正在运行本地 OBS 实例,并且只想从 官方构建服务 或任何其他具有可用 API 服务器的 OBS 实例链接一些软件包,请添加一个 _link 文件,如下所示

<link project='openSUSE.org:openSUSE:Factory' package='tse3'/>

这将把来自openSUSE.org构建服务实例的openSUSE:Factory项目中的软件包tse3链接到您的项目中。

在此示例中,您的构建服务管理员在您的本地实例中创建了一个名为openSUSE.org的空项目,其中包含以下行
<remoteurl>https://api.opensuse.org/public</remoteurl>
在项目定义中。无需进一步管理工作。

针对链接软件包的补丁

> Today I tried to link a package from another project to my project which 
> wasn't a problem. Then I checked out the new package with osc but I only 
> find a "_link"-file in the package dir. So how can I add a patch for 
> example or how can I modify the specfile?

文件可以单独添加到链接项目中。链接项目中的文件会替换原始项目中同名文件。这还包括specfile。补丁文件可用于修补原始项目中的文件,而无需覆盖它们。然后必须在_link文件中指定补丁。

<link project='openSUSE:Factory' package='tse3'>
  <patches>
    <apply name="patch" />
  </patches>
</link>

在链接软件包中添加补丁文件

要将新的补丁文件应用到源代码(除了spec文件中已列出的任何补丁文件),您可以为spec文件创建一个补丁,将补丁添加到spec文件中,并使用<apply>应用,但有一种更简单的方法是使用<add>命令

<link project='openSUSE:Factory' package='tse3'>
  <patches>
    <add name="mybugfix.patch" />
  </patches>
</link>

这将把“mybugfix.patch”添加到spec文件的补丁应用列表中(这是通过构建服务为您插入适当的行到spec文件中实现的)。新补丁将在spec文件中已定义的任何现有补丁之后应用。当然,“mybugfix.patch”必须存在于您的链接项目中。

该<add>命令还支持属性“popt="NUMBER"”以向%patch添加-pNUMBER参数,“dir="some/dir"”以在应用补丁之前更改到some/dir,以及“after="NUMBER"”以在行号NUMBER之后添加%patch。

在spec文件顶部添加一行

要在spec文件顶部添加一行(例如 %define),您无需修补spec文件。相反,您可以使用 <topadd>

<link project="myproject" package="theotherpackage">
  <patches>
    <topadd>%define small_build 1</topadd>
  </patches>
</link>

要获取此文件,请使用 --unexpand-link 参数检出软件包,如下所示

osc checkout --unexpand-link someProject somePackage

在此之后,查找名为 _link 的文件,编辑该文件并将上面所示的代码片段添加到文件中。

要验证所有操作是否成功,请在另一个位置检出软件包,并检查 spec 文件的顶部,它应该包含 <topadd> 标签之间的行。

来源和详细信息:[1]

聚合示例

_aggregate 示例

在您的项目中创建一个新软件包(名称可以与原始软件包相同——但这并非必不可少),并添加一个名为 _aggregate 的文件,内容如下。请注意,_aggregate 通常被认为是糟糕的风格,因为项目需要双倍空间,构建服务可能会推迟您的软件包构建,并且不兼容中断的风险相当高。通常,最好根据下面解释的方式构建更多存储库,以获取其他存储库中的软件包。

<aggregatelist>
  <aggregate project="KDE:Backports">
    <package>ksimus</package>
  </aggregate>
</aggregatelist>

如果存储库名称不匹配,您可以使用 <repository> 元素指定映射(source 是原始软件包的存储库名称)

<aggregatelist>
  <aggregate project="KDE:Backports">
    <package>ksimus</package>
    <repository target="openSUSE_10.2" source="SUSE_10.2" />
    <repository target="openSUSE_10.1" source="SUSE_10.1" />
  </aggregate>
</aggregatelist>

完整语法示例

<aggregatelist>
  <aggregate project="projectname" >
    <package>glibc</package>
    <package>libz</package>
    <binary>gcc</binary>
    <binary>gcc-c++</binary>
    <nosources/>
    <repository target="my_sle_11_repo" source="SLE_11" />
  </aggregate>
  <aggregate project="anotherproject" >
    <binary>gcc</binary>
    <repository target="my_sle_11_repo" source="SLE_11" />
  </aggregate>
  <aggregate project="lastproject" >
    <package>glibc</package>
    <repository target="my_sle_11_repo" source="SLE_11" />
  </aggregate>
</aggregatelist>

在i586上选择i686软件包

如果您想从其他架构而不是默认架构获取软件包(例如i586上的glibc i686),您需要

osc meta prjconf <yourproject> -e

并添加

ExportFilter: \.i686\.rpm$ .

到您的项目配置中。

然后,使用类似以下内容

<aggregatelist>
  <aggregate project="openSUSE:Factory">
    <package>glibc.i686</package>
  </aggregate>
</aggregatelist>

在i586上获取i686软件包。

向项目添加多个存储库

如果一个包依赖(Requires 或 BuildRequires)于多个构建服务存储库,那么向项目添加多个存储库会非常方便。

 osc meta -e prj <project name>

这将打开项目元数据编辑器,使用 <path "projectname"/> 在任何目标下添加更多存储库。请注意,不需要添加依赖存储库。以下示例仅从 openSUSE:Tools 项目添加一个存储库。但是这个项目也针对 openSUSE:10.3/standard 存储库进行构建,因此所有这些包也都会被使用。

 <repository name="openSUSE_10.3">
   <path project="openSUSE:Tools" repository="openSUSE_10.3"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
 </repository>

另一个例子:向 openSUSE:10.2 项目添加 NonFree 和 Update 存储库。基础 openSUSE:10.2/standard 存储库不需要,因为这两个都也针对它进行构建。请注意,添加 :Update 项目通常会导致用户需要所有更新,否则他们会遇到麻烦,而为基础发行版构建应该适用于有和没有更新的用户。唯一的例外是 :Update 存储库是内核模块所需的(因为 Linux 内核经常变得不兼容,而所有其他软件包根据策略不允许变得不兼容)

<repository name="openSUSE_10.2">
   <path project="openSUSE:10.2:Update" repository="standard"/>
   <path project="openSUSE:10.2:NonFree" repository="standard"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

请注意

  • 包含的存储库的顺序很重要:构建服务将尝试使用第一个包含该包的存储库中的包,即使版本不匹配。
  • 依赖项将递归包含
  • 用户必须在他们的系统上配置所有存储库,以便zypper可以在安装时解析Requires:。如果您使用不常见的项目,很难正确猜测它们。
  • 最后的路径列表中的元素(但仅限于最后一个!)由构建服务“展开”。这意味着该元素的project=目标所引用的所有存储库都会隐式包含在项目中,并会搜索其中的软件包。这旨在简化分支。

示例
项目A有

 <repository name="openSUSE_Factory">
   <path repository="snapshot" project="openSUSE:Factory"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

您想在项目 B 中针对项目 A 中的软件包进行构建
使用

 <repository name="openSUSE_Factory">
   <path repository="openSUSE_Factory" project="A"/>
   <path repository="snapshot" project="openSUSE:Factory"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

或者(因为 openSUSE:Factory/snapshot 已经包含在项目 A 中)

 <repository name="openSUSE_Factory">
   <path repository="openSUSE_Factory" project="A"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
</repository>

一个真实的例子,将 devel:languages:python 源添加到您(现有)的存储库中

 <repository name="openSUSE_12.1">
   <path project="devel:languages:python" repository="openSUSE_12.1"/>
   <path project="openSUSE:12.1" repository="standard"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
 </repository>
 <repository name="openSUSE_12.2">
   <path project="devel:languages:python" repository="openSUSE_12.2"/>
   <path project="openSUSE:12.2" repository="standard"/>
   <arch>i586</arch>
   <arch>x86_64</arch>
 </repository>

如何定义构建环境?

它在 build 包的 /usr/lib/build/configs/$distro.conf 中定义。这里有关于此文件中字段的描述

这就是关于构建环境设置的一切。哦,我们还会在这里进行依赖扩展,所以由于包依赖而需要的包会自动添加到“Required”列表中。

构建一个在构建过程中需要X服务器的软件包

这是解决“RuntimeError: Gtk couldn't be initialized”错误的方法。这是因为 openSUSE 12.3 上 python-gobject 的版本存在 bug。
> the package XXXXXX requires an X-server (or
> at least a DISPLAY) to build (without changing the configuration
> files).
>
> Can I access an X-Server in the buildservice?
> What are the required changes in my spec file?

You can run an Xvfb (start it in your specfile) to workaround this problem.

例如,您可以在您的spec文件中使用类似以下代码行

BuildRequires:  xorg-x11-server
%define         X_display         ":98"
...
%install
#############################################
### Launch a virtual framebuffer X server ###
#############################################
export DISPLAY=%{X_display}
Xvfb %{X_display} >& Xvfb.log &
trap "kill $! || true" EXIT
sleep 10
...
# start your application/testsuite here

为不同平台使用不同的spec文件

在一个理想的世界里,您会有一个单一的spec文件,它可以在过去、现在和未来的所有基于 RPM 的平台上运行。然而,在现实中,通常单个spec文件要么不可能,要么需要在您的spec文件中包含如此多的 %if 分支,以至于它将变得难以阅读。

幸运的是,构建服务有一种方法可以为各个平台使用多个 spec 文件。

假设您有一个名为“foo”的软件包,其中包含一个名为“foo.spec”的spec文件。我们假设这个spec文件在基于SUSE的发行版(如openSUSE、SLES和SLED)上运行良好,但由于软件包布局的差异,您确实需要一个单独的spec文件才能为像Fedora这样完全不同的发行版进行构建。如果构建服务中的存储库名为“Fedora_Extras_6”,您可以创建一个名为“foo-Fedora_Extras_6.spec”的spec文件,该文件将仅为该平台构建,而不是使用“foo.spec”。

这唯一的真正缺点是它只适用于单个存储库。无法为多个存储库使用单个 spec 文件。回顾上面的例子,如果您想为 Fedora Extras 4、5 和 6 构建 "foo",您将不得不创建三个 spec 文件:"foo-Fedora_Extras_4.spec"、"foo-Fedora_Extras_5.spec" 和 "foo-Fedora_Extras_6.spec",即使每个 spec 文件都完全相同。

一个实际使用此功能的好例子是 net-snmp 项目中的 "net-snmp-main-snapshot" 软件包

从存储库中删除已禁用但已构建的软件包

目前,Web 前端不支持此功能。在 osc 中,只需键入

osc wipebinaries <projectname> 

您也可以直接与构建服务API“对话”来解决这个问题。如果您想从整个存储库中删除所有标记为已禁用的已构建rpms(在此示例中为:home:foo),请尝试以下方法

  • 创建包含您在 build.opensuse.org 上的登录信息的 ~/.netrc 文件,或者使用 "-u username:password" 选项
  • curl -n -X POST -d '' 'https://api.opensuse.org/build/home:foo?cmd=wipe&code=disabled'
    curl -u username:password -X POST -d '' 'https://api.opensuse.org/build/home:foo?cmd=wipe&code=disabled'

有关更多“命令”,请参阅 API 文档

列出发行版中可用的软件包

当您不知道构建所需的软件包的确切名称时,可以使用 网页搜索 或 osc ls -b。

示例:哪个软件包包含 Ubuntu 上的 mysql 开发文件?

#           <repository> <arch> <project>
$ osc ls -b -r standard -a i586 Ubuntu:7.10 | grep 'mysql.*dev'
libmysqlclient15-dev_5.0.45-1ubuntu3_i386.deb
# -> the package is called "libmysqlclient15-dev"

在构建服务存储库中启用rpmlint检查

请查看 页面和

为其他架构构建xx位软件包 (baselibs)

请参阅 openSUSE:Build Service_baselibs.conf

如何控制生成软件包的发布版本号

通常,BuildService 会自动处理发布标签,因此 Release: 字段的内容会被元组 CI_CNT.B_CNT 替换,其中 CI_CNT 是提交次数,B_CNT 是重新构建次数(当触发重新构建时)。

此行为等同于

Release: <CI_CNT>.<B_CNT>

在 prjconf 中(通过 osc meta prjconf -e [PROJECT] 访问)。

您可以改进它。例如,对于 jpackage.org RPM 的导入,您可以在 prjconf 中定义

Release: %%{?release_prefix}.<CI_CNT>.<B_CNT>

其中rpm宏 %{release_prefix} 在spec文件中定义。生成的rpm将具有与jpackage.org和openSUSE项目兼容的发布版本号。这意味着您将能够将SUSE软件包升级到jpackage.org的软件包。

或者在你的 spec 文件中,如果你的软件包是由 jenkins job 123 生成的,你可以直接写

Release: <CI_CNT>.<B_CNT>.j123

生成的rpm将在其正常的构建发布版本号后附加'.j123',以便您以后可以查看发起构建的jenkins作业。

另请参阅 OBS 手册中关于 构建配置 的章节。

如何修复删除项目时出现的“不存在”错误

当后端超时时,可能会导致 API 数据库和后端之间状态不一致。要删除此类项目,只需使用 osc 编辑其元文件

osc meta prj -e <projectname>

保存它,然后删除它

osc rdelete <projectname>


构建 SLES 11 SP1 LiveCD

经 kiwi-3.74-5.101.1 测试:在构建系统上安装 clicfs-1.1.3-3.1.x86_64.rpm 和 liblzma0-4.999.9beta-11.1.x86_64.rpm,并将这些文件复制到您在 /usr/share/kiwi/image/isoboot/suse-SLES11/config.xml 中配置的存储库目录。

修改文件 /usr/share/kiwi/image/isoboot/suse-SLES11/config.xml,并在 <packages type="bootstrap"> 部分添加以下行 <package name="clicfs"/>

这可能是一个bug,使用这行代码(CD无法启动)无法正常工作

<packages type="bootstrap" profiles="std">

但是使用 type=image,CD 运行良好

<packages type="image" profiles="std">


  1. kiwi --createhash /usr/share/kiwi/image/isoboot/suse-SLES11

修改您的 Live CD 的 config.xml (不是您刚刚编辑的 config.xml) 以使用 clicfs: <type primary="true" boot="isoboot/suse-SLES11" flags="clic">iso</type>

使用squashfs和aufs设置SLES 10 SP2/SP3 KIWI镜像

我的构建主机也是 SLES 10 SP2 x86_64。

这只是一个快速指南,请参阅其他 KIWI 文档。

步骤1 安装KIWI

注意:您可能会在 SLES 10 SDK 存储库中找到一些软件包。我从以下地址安装了当前的 kiwi-3.01-93.1

http://download.opensuse.org/repositories/openSUSE:/Tools/SLE_10

注意:对于kiwi-desc-oemboot和kiwi-desc-vmxboot,您需要qemu,我没有安装它们。

安装智能软件包管理器

rpm -ivh /usr/share/kiwi/repo/suse-repo/suse-sle10-repo/smart-0.41-23.4.$(arch).rpm

http://download.opensuse.org/repositories/home:/mopp:/squashfs/ 下载适用于 SLES 10 SP2/SP3 的 squashfs

http://download.opensuse.org/repositories/home:/mopp:/aufs 下载适用于 SLES 10 SP2/SP3 的 aufs

在KIWI服务器上安装squashfs包

rpm -ivh /tmp/kiwi/squashfs-3.4-35.1.x86_64.rpm

步骤2 创建KIWI启动镜像环境

当然,您需要 SLES 10 SP2/3 源,我将它们复制到本地目录。请根据您的系统更改路径。

cp -a aufs-kmp* squashfs-kmp* /usr/share/kiwi/repo/suse-repo/suse-sle10-repo/

注意:aufs 和 squashfs 模块安装在 /lib/modules/<kernel>/updates/。请确保内核模块与您在 KIWI 镜像中安装的内核匹配。

现在是时候修改config.xml(boot/initrd镜像)以找到aufs和squashfs模块了。也许您可以在编辑之前复制目录,因为更新kiwi后,config.xml可能会被覆盖。

cd /usr/share/kiwi/image/isoboot/suse-SLES10
vi config.xml

非常重要的一点是,将aufs和squashfs添加到<drivers type="drivers">部分中。添加这些行,否则LiveCD将无法找到。

<file name="../updates/aufs.ko"/>
<file name="../updates/fs/squashfs/*"/>

向 <packages type="bootstrap"> 部分添加以下行

<package name="squashfs-kmp-default"/>
<package name="squashfs-kmp-smp"/>
<package name="aufs-kmp-default"/>
<package name="aufs-kmp-smp"/>

创建新的哈希

kiwi --createhash /usr/share/kiwi/image/isoboot/suse-SLES10

步骤3 准备系统镜像

确保您没有混淆启动镜像内核和系统镜像内核之间的内核(-default 和 -smp)。

准备系统镜像(我使用了 suse-11.0 配置,因为它是一个最小配置)

cp -pr /usr/share/doc/packages/kiwi/examples/suse-11.0/suse-live-iso /usr/local/kiwi/suse-sle10sp2-live-iso

编辑 /usr/local/kiwi/suse-sle10sp2-live-iso 中的 config.xml,至少您必须更改 "boot" 标签和 "repository"

更改

<type primary="true" boot="isoboot/suse-11.0" flags="unified">iso</type>

<type primary="true" boot="isoboot/suse-SLES10" flags="unified">iso</type>

删除软件包“bootsplash-branding-openSUSE”,因为它在SLES 10上不可用。

您需要添加存储库以查找其他软件包,例如smart。

       <repository type="rpm-dir">
               <source path="/usr/share/kiwi/repo/suse-repo/suse-sle10-repo/"/>
       </repository>

在 config.xml 中添加或删除您需要的包,并自定义您的系统。

您可以添加 dhcpcd 软件包以启用 dhcp。

opensusePattern 似乎不适用于 SLES。

步骤4 创建ISO镜像

确保您有足够的可用空间。

kiwi --prepare /usr/local/kiwi/suse-sle10sp2-live-iso --root /tmp/myiso

检查日志文件。要检查创建的目标系统,您可以执行

chroot /tmp/myiso

如果一切正常,是时候创建iso镜像了

kiwi --create /tmp/myiso -d /tmp/myiso-result

检查日志文件。

尝试启动ISO镜像

从VCS检出执行夜间构建

OBS 现在支持通过 _service 文件直接从 VCS 下载。请参阅此概念页面OBS 参考指南

如果您想使用 _service 文件技术并避免解析/编辑 .spec 文件,甚至允许与 debian 打包共享版本信息,请尝试 https://github.com/boombatower/obs-git-update。否则请继续阅读。

您需要一台安装有 cronosc 的机器。

准备一个工作目录,其中包含您的代码的 VCS 检出和构建服务中您的软件包的检出。准备一个 spec 文件模板,并在版本字段中留一个占位符。它可能看起来像这样

Name:         monitord
Version:      ##TIMESTAMP##
Requires:     alsa
...

准备一个 shell 脚本,用于进行本地更新、准备 tarball、修改 spec 文件并将文件上传到构建服务。

这是一个 SVN 存储库的示例脚本

#!/bin/bash

# the relative path to the OBS checkout
PACK_PATH=home:cwh:monitord-nightly/monitord

# the relative path to the SVN checkout
REPO_PATH=trunk

TIMESTAMP=`date +"%Y%m%d"`

# enter SVN directory
pushd $REPO_PATH

# update to current revision
svn up

# prepare tarball
make dist

# move resulting tarball to the package directory 
cp monitord-2.0svn.tar.gz ../$PACK_PATH

popd

# copy a modifyed spec file to the package directory
perl -p -e "s/##TIMESTAMP##/$TIMESTAMP/" monitord.spec > $PACK_PATH/monitord.spec

# enter package directory
pushd $PACK_PATH

# upload changes (new tarball and spec file) to the OBS
osc commit -m "updated to current SVN snapshot $TIMESTAMP"

popd

echo "Done"

然后通过 cron 调用此脚本。

示例

0 5 * * *       cd /space/monitord-nightly && ./push_to-obs.sh