我正在构建一个需要以root身份运行bash脚本的RPM。
spec文件的%install
节是:
%install
cp %{SOURCE1} %{SOURCE2} %{_tmppath}/%{name}-%{version}-%{release}
cd %{_tmppath}/%{name}-%{version}-%{release}
chmod u+x %{installscript}
sudo ./%{installscript}
其中%{installscript}
是以root用户身份运行的脚本。
rpmbuild
执行%{installscript}并创建RPM(没有问题)。
但是,当我安装RPM时:
$ sudo rpm -Uvh $rpmpath
Preparing... ########################################### [100%]
1:tty-cap ########################################### [100%]
$
%{installscript}
脚本未执行。
我尝试通过将脚本调用移动到%post
节来更改spec文件:
%install
cp %{SOURCE1} %{SOURCE2} %{_tmppath}/%{name}-%{version}-%{release}
cd %{_tmppath}/%{name}-%{version}-%{release}
%post
chmod u+x %{installscript}
sudo ./%{installscript}
但是%post
似乎没有做任何事情。
如何打包安装时会执行脚本的RPM?
在查看下面的有用评论之后,这里是一个带有%post
节的spec文件,在RPM安装期间实际执行该文件。
但是,脚本%{installscript}
不与用户交互(就像从shell运行时那样),但似乎在没有用户交互的情况下接受所有默认值。
我应该更改哪些内容以便脚本与rpm
命令用户进行交互?
$ cat ~/RPMBUILD/SPECS/demo.spec
#
# %_topdir and %_tmppath are defined in ~/.rpmmacros
%define name tty-cap
%define version 5.2
%define release 1
%define buildroot %{_tmppath}/%{name}-%{version}-%{release}
%define tarversion tty-5.2.0-00-70270
%define tarfile %{tarversion}.tar
%define installscript tty.install.sh
Name: %{name}
Version: %{version}
Release: %{release}
BuildArch: noarch
Summary: Bla
License: Proprietary
Source1: %{installscript}
Source2: tty-5.2.0-00-70270.tar
Prefix: /opt/Intellinx/TTYCapture
BuildRoot: %{_builddir}/%{name}-root
%description
Demonstration RPM
%prep
%build
%install
cp %{SOURCE1} %{SOURCE2} %{_tmppath}/%{name}-%{version}-%{release}
cd %{_tmppath}/%{name}-%{version}-%{release}
%clean
[ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT}
%post
echo ">>> Inside post <<<"
chmod u+x %{installscript}
./%{installscript}
%files
%define tmp /
%{tmp}/%{tarfile}
%{tmp}/%{installscript}
$ rpmbuild -v -bb ~/RPMBUILD/SPECS/demo.spec
Executing(%prep): /bin/sh -e /home/ronbarak/RPMBUILD/tmp/rpm-tmp.oEOM10
+ umask 022
+ cd /home/ronbarak/RPMBUILD/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ exit 0
Executing(%build): /bin/sh -e /home/ronbarak/RPMBUILD/tmp/rpm-tmp.qQFuTA
+ umask 022
+ cd /home/ronbarak/RPMBUILD/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ exit 0
Executing(%install): /bin/sh -e /home/ronbarak/RPMBUILD/tmp/rpm-tmp.8rTMLa
+ umask 022
+ cd /home/ronbarak/RPMBUILD/BUILD
+ '[' /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1 '!=' / ']'
+ rm -rf /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
++ dirname /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
+ mkdir -p /home/ronbarak/RPMBUILD/tmp
+ mkdir /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
+ LANG=C
+ export LANG
+ unset DISPLAY
+ cp /home/ronbarak/RPMBUILD/SOURCES/tty.install.sh /home/ronbarak/RPMBUILD/SOURCES/tty-5.2.0-00-70270.tar /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
+ cd /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/brp-python-bytecompile
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Processing files: tty-cap-5.2-1.noarch
Requires(interp): /bin/sh
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires(post): /bin/sh
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
Wrote: /home/ronbarak/RPMBUILD/RPMS/noarch/tty-cap-5.2-1.noarch.rpm
Executing(%clean): /bin/sh -e /home/ronbarak/RPMBUILD/tmp/rpm-tmp.Yag9bm
+ umask 022
+ cd /home/ronbarak/RPMBUILD/BUILD
+ '[' /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1 '!=' / ']'
+ rm -rf /home/ronbarak/RPMBUILD/tmp/tty-cap-5.2-1
+ exit 0
$ sudo rpm -Uvh /home/ronbarak/RPMBUILD/RPMS/noarch/tty-cap-5.2-1.noarch.rpm
Preparing... ########################################### [100%]
1:tty-cap ########################################### [100%]
>>> Inside post <<<
###### Starting tty capturing installation ######
Specify installation directory full path [/opt/Intellinx/TTYCapture]:
/opt/Intellinx/TTYCapture already exists. continue installation? (y/n) [y]
Extracting archive tty-5*.* ...
Please specify TTY sensor owner user [ronbarak]:
TTY sensor will be accessible by user 'ronbarak' in group 'ronbarak'
Specify sensor working directory full path [/opt/Intellinx/TTYCapture/work]:
Specify sensor listening port [1024-65000] [8888]:
Do you want to register the sensor service? (y/n) [n]
Server gxttySensorService is not register as a daemon
Executing default user shell (y/n) [y]
TTY capturing has been installed successfully.
答案 0 :(得分:4)
您在这里混合了几个概念。所以让我们退一步。
在%prep
部分,您应该解压缩%{SOURCE0}
并应用补丁(如果有的话)。这通常是
%setup -q
但是,如果您需要,可以手动提取。有关此宏的详细信息,请参阅http://www.rpm.org/max-rpm/s1-rpm-inside-macros.html
在%build
部分中,您通常将源代码编译为二进制文件。如果您使用解释语言或者您的tar包含已编译的二进制文件,则可能为空。
在%install
部分中,您应该将文件复制到%{buildroot}
并创建将在包中登陆的结构。例如。 %{buildroot}/etc/yourconfig
,%{buildroot}/usr/bin/yourcommand
等。您可以在那里运行任何您想要的脚本,但请记住,它只能在构建时间中运行。即仅在您的机器(或构建系统)上。这用于创建自动生成的文件(例如,源代码中的库文档)。
然后,在安装软件包之后,您将在用户计算机上运行部分%post
。并且所有文件都安装在最终路径中。不在buildroot。在开始时,您将更改为/
,因此您需要在该用户计算机上指定完整路径。
所以在你的情况下它应该看起来像:
%install
mkdir -p %{buildroot}%{_bindir}
cp -a %{installscript} %{buildroot}%{_bindir}/
chmod a+x %{buildroot}%{_bindir}/%{installscript}
%files
%{_bindir}/%{installscript}
%post
%{_bindir}%{installscript}
Sever注意到:
%post
部分在root下执行,因此不需要sudo。
强烈建议不要运行交互式脚本。 RPM被设计为非交互式的,并且每个实用程序在包安装期间都不承担任何交互(例如PackageKit,Spacewalk等)。所以很快你会得到一些收益。用户在手动安装后运行某些命令(或使用Ansible或Puppet自动运行)会更安全。