I have a spec file which is similar to:
BuildRoot: /tmp/build_%{name}-%{version}-%{release}
%prep
...
...
%install
# Directories
install -m 755 -d %{buildroot}/usr/app/mypackage/config
install -m 755 -d %{buildroot}/usr/app/mypackage/src
....
# Bash script
install -m 755 script/script1.sh %{buildroot}/usr/app/mypackage/config/script1.sh
install -m 755 script/script2.sh %{buildroot}/usr/app/mypackage/config/script2.sh
install -m 755 script/myapp-log %{buildroot}/etc/logrotate.d/myapp-log
When I run the rpmbuild I get the error:
install: cannot create regular file `/tmp/build_my_app-1.0-2/etc/logrotate.d/myapp-log'
I can get around this by manually creating the /etc/ and then /etc/logrotate.d directories in the /tmp/build_my_app-1.0-2/ directory.
When I re-reun the rpmbuild it will work.
I guess this is because I am not creating this directory in my install section but as its not directly related to my application I don't want to put that in.
My guess is that there is some clever tag I can use to fix this so that the build will work without any manual intervention.
My Question:
Could someone please suggest a way for me to achieve this (assuming its possible) or whether I need to write a script around the rpmbuild to set this up first.
You are missing the step to create the installation directories in your %install section. Remember that since you can build in "different" roots, you cannot expect certain directories (like ${buildroot}/etc) to be present.
Try adding
mkdir -p ${buildroot}/etc/logrotate.d
just before the install command that copies the file into ${buildroot}/etc/logrotate.d.
Related
I am working on an RPM which unpackages a tar file into an RPM whenever I run rpmbuild. I have two questions around the process:
Is my process of unpackaging the tar file into the RPM correct?
When I install the actual rpm onto a server, I'd like it to run a script inside the RPM which I have copied in called install.sh. How do I do that?
%build
# let's skip this for now
%install
mkdir -p %{buildroot}
chmod 755 ~/rpmbuild/SOURCES/bin/*
cp -frv ~/rpmbuild/SOURCES/bin/* %{buildroot}
%files
/*
%changelog
# let's skip this for now
Generally RPM support pre and post installation/uninstall scripts. And they are defined with %pre, %post, %preun and %postun. So if you are sure this file (install.sh) already exist you can run it on this way:
%pre
/path/to/install.sh
or
%post
/path/to/install.sh
I have taken over a Yocto project, and inside a .bb recipe file, I see the following lines to install new directories in the image:
do_install() {
install -m 0755 -d ${DEPLOY_DIR_IMAGE}/app
install -m 0755 -d ${DEPLOY_DIR_IMAGE}/app/apiary
install -m 0755 -d ${DEPLOY_DIR_IMAGE}/app/lib
install -m 0755 -d ${DEPLOY_DIR_IMAGE}/app/config
install -m 0755 -d ${DEPLOY_DIR_IMAGE}/app/scripts
install -m 0755 -d ${DEPLOY_DIR_IMAGE}/app/keys
This works but I am confused. From my reading about Yocto and doing do_install, I thought that the -m option is only for installing files and not directories.
What is the effect of doing install -m 0755 -d , both the -m and -d options with the install command?
Also, why is there no ${D} variable like in the majority of other directory installations which I see?
I normally wouldn't resort to Stack Overflow for a question like this, but there is so much inconsistency that I don't understand , and hard to find an answer.
The task in question is defined as a shell function. The install command used within is a shell command, not anything Yocto- or BitBake-specific, so you should be looking at its docs for enlightenment, not relying on BitBake documentation or examples. In the context of Yocto in particular, however, you should be looking at the documentation for the GNU coreutils version of the install program (as linked above), which is the one you will invariably find on Linux systems.*
From my reading about Yocto and doing do_install, I thought that the -m option is only for installing files and not directories.
I'm not sure what would make you think that, other than just not seeing it applied to directories before.
What is the effect of doing install -m 0755 -d, both the -m and -d options with the install command?
The -m option sets the mode (access-control bits) of the installed object(s). Directories have modes just like regular files do, and the -m option has the same meaning for installing directories as it does for installing regular files.
The -d option specifies that the names specified for installation are to be taken as directories to be created, along with any missing directories in the specified path. As #jww observed in comments, the effect is analogous to that of mkdir -p.
These options are orthogonal. When used together, their effects combine in the natural way: the specified directories are created, with parent directories if needed, and all directories created are assigned the specified mode. Setting the modes explicitly to 0755 is superfluous, however, because that's the default. That may be why you are not used to seeing -m options used for directories.
Also, why is there no ${D} variable like in the majority of other directory installations which I see?
The Yocto specifications for do_install say that it should install files relative to ${D}, whereas the variable DEPLOY_DIR_IMAGE refers to the location for ready-to-install images. It seems like installing to ${DEPLOY_DIR_IMAGE} would be the wrong thing to do, but that doesn't necessarily mean that it wouldn't produce the desired ultimate effect. Or perhaps the recipe was simply written for some older version of BitBake where it made more sense. In any event, sorting out the the details would be a much deeper and more involved analysis than I am prepared to perform for you.
*install is not standardized by POSIX. The GNU version was inspired by BSD's program of the same name, and current versions of that have similar options and behavior, including specifically with respect to the -m and -d options.
Can I set permissions when I create a file/directory using a single command or do I have to create the file/directory first and then use chmod to set its permissions?
For instance to do something like this
// for directories
mkdir 755 test
// for files
touch 644 test/my_file.php
For files, try using install command:
$ install -m 644 /test/path/ myfile.php
For folders, mkdir with -m param:
$ mkdir -m 755 test
You might have to execute that as sudo.
Man pages are your friend. This is possible with GNU mkdir but not with GNU touch.
mkdir -m 755 test
you can use following command to create directory and give permissions at the same time
mkdir -m755 test
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I've 2 files which include shell command to be execute ,, and I've one iptables-save which include chain need to installed
How can I write the spec file to:
copy my 2 shell files to /etc/
execute iptables-restore < /home/iptables-save
P.S: I went through this how-to. Unfortunately I'm newbie in this, I
couldn't find the solution.
Had to do this just yesterday.
Create your build directory in your home as a normal user don't use root, just smart that way.
mkdir -p ~/rpmbuild/BUILD
mkdir -p ~/rpmbuild/BUILDROOT
mkdir -p ~/rpmbuild/RPMS
mkdir -p ~/rpmbuild/SOURCES
mkdir -p ~/rpmbuild/SPECS
mkdir -p ~/rpmbuild/SRPMCS
mkdir -p ~/rpmbuild/tmp
Next create rpmmacros so that rpmbuild knows where to build, contents of ~/.rpmmacros should
contains the following
%packager Chris Hinshaw
%_topdir /home/chinshaw/rpmbuild
%_tmppath /home/chinshaw/rpmbuild/tmp
Next create the rpm spec found in ~/rpmbuild/SPECS/ . This example spec file will handle a script called demo script, it's configuration file that goes in etc and a third cron script that will schedule the script to run hourly.
~/rpmbuild/SPECS/demoproject.spec
Name: demoproject
Version: 0.1
Release: 1%{?dist}
Summary: Demo script for doing something cool
Group: DemoGroup
License: GPL
Source0: demoproject-0.1.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description
Demo project that does something interesting
%prep
%setup -q
%build
%install
install --directory $RPM_BUILD_ROOT/usr/sbin
install --directory $RPM_BUILD_ROOT/etc
install --directory $RPM_BUILD_ROOT/etc/cron.d/
install -m 0755 demoscript $RPM_BUILD_ROOT/usr/sbin
install -m 0744 demoscript.conf $RPM_BUILD_ROOT/etc
install -m 0744 cron/democronscript $RPM_BUILD_ROOT/etc/cron.d/
%clean
rm -rf $RPM_BUILD_ROOT
%files
/usr/sbin/demoscript
/etc/demoscript.conf
/etc/cron.d/democronscript
%changelog
The only quirk I found was that I really needed to tar up my 3 source files in a tarball which seemed like a good idea anyway.
The contents or the rpmbuild/SOURCES directory should look like this.
$ cd ~/rpmbuild/SOURCES
$ ls
demoproject-0.1.tar.gz
$ tar -tvzf demoproject-0.1.tar.gz
demoproject-0.1/
demoproject-0.1/demoscript.conf
demoproject-0.1/demoscript
demoproject-0.1/cron/
demoproject-0.1/cron/democronscript
then all you have to do is build it
rpmbuild -ba ~/rpmbuild/SPECS/demoproject.spec
This will create arch rpms and srpms and land them in the ~/rpmbuild/RPMS and ~/rpmbuild/SRPMS directories.
Use the %post and %preun sections to run actions after installing and before deinstalling and just put your shell commands there.
I need to create the following symbolic links into RPM file
/bin/ln -sf libcrypto.so.0.9.8e /lib/libcrypto.so.0.9.8
/bin/ln -sf libssl.so.0.9.8e /lib/libssl.so.0.9.8
In my RPM spec file:
%files
%defattr(-,root,root)
/lib/libcrypto.so.0.9.8
/lib/libssl.so.0.9.8
<other files...>
%install
/bin/ln -sf libcrypto.so.0.9.8e /lib/libcrypto.so.0.9.8
/bin/ln -sf libssl.so.0.9.8e /lib/libssl.so.0.9.8
The /lib/libcrypto.so.0.9.8e and /lib/libssl.so.0.9.8e are exists on my PC, but when I'm trying to install my RPM, I got an error:
libcrypto.so.0.9.8 is needed by my-test-rpm-1.el5.i686
libssl.so.0.9.8 is needed by my-test-rpm-1.el5.i686
What wrong? What I need to do in order to create symbolic links as part of the RPM installation?
Thanks
As workaround I disabled automatic dependency processing by adding:
AutoReqProv: no
to my spec file.
I'm still looking for the real solution.
You need to run ldconfig in the %post part of the spec file:
%post
umask 007
/sbin/ldconfig > /dev/null 2>&1
%postun
umask 007
/sbin/ldconfig > /dev/null 2>&1
should do it.
1) Just for symlinks you don't need to call ldconfig at post stage.
2) As already mentioned by ldav1s: Be sure that your files are listed in %files section.
3) Once again: Be sure that your files are listed - especially if you use something like
%define _unpackaged_files_terminate_build 0
RHEL rpmbuild terminates with an error if files are found in buildroot which are not listed in %files section. With this define you can switch the behaviour/error off but you should exactly know what you are actually doing. If you use this line you should remove it from your spec file.
4) Don't build the rpm package as user root. If you forget to use rpm_build_root you won't destroy your live system. Your example looks like it was taken from a spec file of Red Hat 4.2 of 1997. Since Red Hat 5 (not RHEL 5!) in 1997 the rpm/rpmbuild command knows the RPM_BUILD_ROOT definition. I guess that this is your problem: You don't use the buildroot but install directly into the root FS and run rpmbuild as user root.
Given your example it should be changed to:
%install
/bin/ln -sf libcrypto.so.0.9.8e $RPM_BUILD_ROOT/lib/libcrypto.so.0.9.8
/bin/ln -sf libssl.so.0.9.8e $RPM_BUILD_ROOT/lib/libssl.so.0.9.8
Using buildroot is described in RPM docs.
The best way to do this is by preventing the symlinks you created from being scanned by the automatic depends & requires generators:
%filter_provides_in libcrypto.so.0.9.8e
%filter_provides_in libssl.so.0.9.8e
%filter_requires_in libcrypto.so.0.9.8e
%filter_requires_in libssl.so.0.9.8e
%filter_setup
More information on depends/requires filtering here.