Create symlink in RPM

13,373

Solution 1

You should not create symlink in %post. One of many reason is that this symlink is then not owned by rpm package. If the symlink is owned by rpm package, then rpm handle it removal during upgrade itself.

Please see: https://stackoverflow.com/a/32073947/3489429

Solution 2

The given spec-file installs cdplayer-1.1-bin.jar, but links to cdplayer-1.1.jar. Here is a diff showing changes I made to get it to work as intended:

--- foo.spec.orig   2015-11-16 20:34:48.000000000 -0500
+++ foo.spec        2015-11-16 20:44:08.017874483 -0500
@@ -1,21 +1,25 @@
 %define base_install_dir %{_datadir}/prog

+Summary: sample rpm spec-file
+License: unknown
 Name:cdplayer
 Version:1.1
 Epoch:1
 Release:2el6
-Source:cdplayer-1.1-bin.jar
+Source:%{name}-%{version}-bin.jar
 BuildArch:noarch
+%global actual %{name}-%{version}.jar
+%global linked %{name}.jar
 %description    
 %prep
 %install
 %{__mkdir} -p %{buildroot}%{base_install_dir}
-%{__install} -D -m 755 %{SOURCE0} %{buildroot}%{base_install_dir}
+%{__install} -D -m 755 %{SOURCE0} %{buildroot}%{base_install_dir}/%{actual}

 %post
-ln -s -f /usr/share/prog/cdplayer-1.1.jar /usr/share/prog/cdplayer.jar
+ln -s -f %{base_install_dir}/%{actual} %{base_install_dir}/%{linked}
 %postun
-%{__rm} -f /usr/share/prog/cdplayer.jar
+%{__rm} -f %{base_install_dir}/%{linked}
 %files
 %defattr(-,root,root,-)
 %dir %{base_install_dir}

There are a few problem areas in your spec-file to explore:

  • there is a flaw in the way upgrades are handled which would appear if you used yum (see Own RPM package: Make symlink survive update/freshen for example, which checks for the state before removing the link as a side-effect of package upgrade versus removal).
  • you are using the epoch tag which requires care, but the question gives no clue about the steps you use regarding it for upgrades.
  • if you install the package directly, for example, just changing the epoch value, you can end up with multiple copies of the same package.

Adding a -v option to the rm and ln commands would show you more clearly what the package does when you install it.

Share:
13,373
Arani
Author by

Arani

Updated on August 06, 2022

Comments

  • Arani
    Arani over 1 year

    I have a specific version of a software on Linux and I am packaging a .jar file (meant to upgrade the existing software) in an rpm and then trying to re-create a symlink to point to the latest version of the jar. I tried using %post and %postun to create and delete the symbolic link (in case it exists already), however this does not work. I have seen a few posts on the internet, but they did not work.

    As a workaround, I tried to create the symlink in puppet. For this I used something like below:

    if $version == ‘1.1'  {
        file { '/usr/share/prog/software.jar':
        ensure  => 'symlink',
        target  => '/usr/share/prog/java/software-1.1-bin.jar',
    }
    

    But even here, the new version jar is getting created, but not the symlink.

    Please let me know if anybody has solved this problem before.

    Below is the spec file that I had used:

    %define base_install_dir %{_datadir}/prog
    
    Name:cdplayer
    Version:1.1
    Epoch:1
    Release:2el6
    Source:cdplayer-1.1-bin.jar
    BuildArch:noarch
    %description    
    %prep
    %install
    %{__mkdir} -p %{buildroot}%{base_install_dir}
    %{__install} -D -m 755 %{SOURCE0} %{buildroot}%{base_install_dir}
    
    %post
    ln -s -f /usr/share/prog/cdplayer-1.1-bin.jar /usr/share/prog/cdplayer.jar
    %postun
    %{__rm} -f /usr/share/prog/cdplayer.jar
    %files
    %defattr(-,root,root,-)
    %dir %{base_install_dir}
    %{base_install_dir}/*
    
    %changelog
    
  • Arani
    Arani over 8 years
    That is not the actual issue. This has been taken care of in my code and still does not create link.
  • Thomas Dickey
    Thomas Dickey over 8 years
    Then something differs in your example from the actual - I did a test-install, and my modified spec-file worked as expected.