If condition inside the %Files section on a SPEC file
Asked Answered
B

4

8

I'm kinda a new to writing spec files and building RPM's. Currently I have one RPM that is supposed to deploy some files in 1 of 2 possible directories that will vary with the OS.

How can I, within the %files section, verify them? I can't use variable...I can't verify both paths because one will for sure fail...I tried to define a macro earlier in the %install section but it will be defined just once and won't be redefined on every RPM installation...

what can I do here?

Thanks

Bedight answered 9/9, 2013 at 15:27 Comment(0)
A
3

The %files section can have variables in it, but usually this would be something like your path that is defined so you don't have to repeat it a bunch. so %{long_path}/file_name, where long_path was defined earlier in the spec file. the %files section is all the information that goes into the RPM database, and is created when you build the RPM so you won't be able to change those values based on machine information when installed.

If you really want to do this, you could include a tar file inside of the main tarball that gets extracted depending on certain conditions (since the spec file is just bash). Now keep in mind this is an awful idea. The files won't be tracked by the RPM database, so when you remove the RPM these files will still exist.

In reality you should build two RPMs, this will allow for better support going forward into the future in the event you have to hand this off to someone, as well as preserving your own sanity a year from now when you need to update the RPM.

Additional answered 10/9, 2013 at 5:32 Comment(3)
so, your idea is to build two different RPM's, with the same content but that will check the %files in different paths? Yes, that sounds like a good idea, making two RPMs for two different kinds of OS...Bedight
but is it somehow possible to have a if condition inside the %files ?Bedight
You could have an if condition in the RPM for what goes into the %files section during the build of the RPM itself, but that won't work on install. That files list is basically static. You also run into the issue where you'll get an error saying that RPM found files (during the build), but they were unpackaged (because they live in your tarball, but aren't declared in the %files section due to your if statement). In general I'd try to stay away from doing that.Additional
S
5

I had a similar situation where additional files were included in the RPM in case of a DEBUG build over and above all files in the RELEASE build.

The trick is to pass a list of files to %files alongwith a regular list of files below it:

%install
# Create a temporary file containing the list of files
EXTRA_FILES=$RPM_BUILD_ROOT/ExtraFiles.list
touch %{EXTRA_FILES}

# If building in DEBUG mode, then include additional test binaries in the package
%if %{build_mode} == "DEBUG"
# %{build_mode} is a variable that is passed to the spec file when invoked by the build script
# Like: rpmbuild --define "build_mode DEBUG"
echo path/to/file1 > %{EXTRA_FILES}
echo path/to/file2 >> %{EXTRA_FILES}
%endif

%files -f %{EXTRA_FILES}
path/to/release/file1
path/to/release/file2

In your case, you can leverage the %if conditional in the %install section, use the OS as a spec variable passed to rpmbuild (or detect it in the RPM spec itself) and then pass the file containing the list to %files

Sphygmic answered 30/1, 2014 at 14:10 Comment(0)
M
4

This is how I solved my problem

step 1 :

   In Build section .. somewhere I wrote :
 %build
  .....
  #check my condition here & if true define some macro
  %define is_valid %( if [ -f /usr/bin/myfile ]; then echo "1" ; else echo "0"; fi )
 #after his normal continuation
 .....
 ...

Step 2: in install section

  %install
  ......
  #do something in that condition
  if %is_valid
  install -m 0644 <file>
  %endif
  #rest all your stuff
  ................

Step 3:in files section

   %files
   %if %is_valid 
   %{_dir}/<file>
   %endif

That's it

It works.

PS : I cannot give you full code hence giving all useful snippet

Mitsue answered 5/2, 2015 at 12:43 Comment(1)
Looks like you forgot percent symbol here %if %is_valid. Anyway thanks for your answer, it helped me.Brazilein
A
3

The %files section can have variables in it, but usually this would be something like your path that is defined so you don't have to repeat it a bunch. so %{long_path}/file_name, where long_path was defined earlier in the spec file. the %files section is all the information that goes into the RPM database, and is created when you build the RPM so you won't be able to change those values based on machine information when installed.

If you really want to do this, you could include a tar file inside of the main tarball that gets extracted depending on certain conditions (since the spec file is just bash). Now keep in mind this is an awful idea. The files won't be tracked by the RPM database, so when you remove the RPM these files will still exist.

In reality you should build two RPMs, this will allow for better support going forward into the future in the event you have to hand this off to someone, as well as preserving your own sanity a year from now when you need to update the RPM.

Additional answered 10/9, 2013 at 5:32 Comment(3)
so, your idea is to build two different RPM's, with the same content but that will check the %files in different paths? Yes, that sounds like a good idea, making two RPMs for two different kinds of OS...Bedight
but is it somehow possible to have a if condition inside the %files ?Bedight
You could have an if condition in the RPM for what goes into the %files section during the build of the RPM itself, but that won't work on install. That files list is basically static. You also run into the issue where you'll get an error saying that RPM found files (during the build), but they were unpackaged (because they live in your tarball, but aren't declared in the %files section due to your if statement). In general I'd try to stay away from doing that.Additional
G
1

Forrest suggests the best solution, but if that is not possible practical you can detect the OS version at runtime in the post-install section, move the script to the appropriate location, and then delete it post-uninstall, eg:

# rpm spec snippets
%define OS_version %(hacky os detection)
...
Source2: script.sh
...
%install
install %{_sourcedir}/script.sh %{buildroot}/some/known/location
...
%post

%if %{OS_version} == "..."
  mv /some/known/location/script.sh /distro/specific/script.sh
%elif %{OS_version} == "..."
...

%preun
rm -rf /all/script/locations

Much more error prone than building different RPMs on different OSes, but will scale a little better if you need to support many different OSes.

Gallicize answered 30/10, 2013 at 21:57 Comment(1)
RPM4 has no elif / elsif / elseif directive.Emelina

© 2022 - 2024 — McMap. All rights reserved.