openSUSE:Cron rename
Intro
When I tried rename package cron to cronie I meet with few serious issues and I didn't found docs how to resolve them (If you got it please correct me). All I have found is http://en.opensuse.org/Package_Dependencies#Renaming_a_package : I should use classical Provides:
and Obsoletes:
. But after little investigation I found, that this solution doesn't cover case when package contain init script with daemon.
Example of proper package update
Firstly lets start with normal update (e.g. update from cron 4.1 to cron 4.2). Common way in (openSUSE) how to deal with update process in package which contain init script (and sysconfig) is using macros in %post
%preun
and %postun
in spec file. These macros restart/stop/insert service if needed, clean up services or fill up syconfig files. Common and quick way how to check content of macro, is using rpm --eval
(e.g. :rpm --eval %stop_on_removal
). But I recommend using vim /usr/lib/rpm/suse_macros
and check here SUSE specific macro (or use other file from /usr/lib/rpm/
dir). rpm --eval
could expand macro, which is realy sometimes confusing.
... %post %{fillup_and_insserv -y cron} ... %preun %stop_on_removal cron %postun %restart_on_update cron %insserv_cleanup ...
In example above (during update process) %postun
and %preun
scriptlets are called from older version, %post
and %preun
are called from new version of cron. Check this link to see scriptlet ordering :http://en.opensuse.org/Packaging/Scriptlet_Snippets#Scriptlet_Ordering
But now lets see how update process works:
update : one process when scriptlets could interact between packages | |||||||
Scriptlet from cron 4.2 package |
| ||||||
---|---|---|---|---|---|---|---|
Scriptlets from cron 4.1 package |
|
Package rename
As I mention you could hit few issues during rename process because rename is not update ! All macros which check FIRST_ARG ($1) doesn't do the job (e.g. %stop_on_removal cron), see more info about FIRST_ARG : http://en.opensuse.org/Packaging/Scriptlet_Snippets#Syntax This leads to :
- rc states are not in proper states after install
- process (daemon) state is not in proper states after install
Why the same spec doesn't do the job
Lets see what happen when we try to run "zypper dup","zypper in" or "rpm -U" cronie-1.4.4xx.rpm (which obsoletes cron 4.1) and we use standard Provides/Obsoletes way:
Name: cronie Version: 1.4.4 ... Provides: cron = 4.2 Obsoletes: cron <= 4.1
rename : one process when scriptlets could interact between packages | |||||||
Scriptlet from cronie 1.4.4 package |
| ||||||
---|---|---|---|---|---|---|---|
Scriptlets from cron 4.1 package |
|
So at the end we finish always with stopped daemon and services turned on
Modified spec to cover all issues
So how to deal with rename ? There is a lot of solution and probably this bellow isn't the best, but could be helpful. The main idea is using main package cronie with subpackage cron, Subpackage cron have newer version than old cron so it will do update. So basically we will do :
update cron 4.1 -> 4.2 + install cronie
In update cron process we will save configs and we will use them during install phase of cronie.
Check also useful info about config files and update process.
Enlarging the spec file
Name: cronie Version: 1.4.4 PreReq: cron Conflicts: cron <= 4.1 .. %package -n cron Version: 4.2 Requires: %{name} = %{cronie_version}-%{release}
%pre -n cron # check if we are doing "ugly" update from old 4.1 vixie-cron check_cron_mail_feature=`/usr/sbin/cron --help 2>&1 | /usr/bin/grep mail` # vixie-cron 4.1 doesn't contain mail fature if [ -e /usr/sbin/cron -a "${check_cron_mail_feature}" == "" ]; then # save configs for cronie post-install phase touch /var/run/update_from_old_cron for conf in %{cron_configs} do %__mv "$conf" "$conf.bk" ||: done fi %pre if [ -e /var/run/update_from_old_cron ]; then # restore configs for conf in %{cron_configs} do %__mv "$conf.bk" "$conf" ||: done fi %post echo "post-install of cronie package" # when we are doing rename then we pretend update with set 2 if [ -e /var/run/update_from_old_cron ]; then set 2 %restart_on_update cron # in %postun restart_on_update call try-restart but we don't have init script in this phase when # we are doing "ugly" update, but don't panic, it produces only warning to stderr echo "Please ignore message about missing init script(from postun) - when occurs, we will ....." %__mv /etc/init.d/cron /etc/init.d/cron.bk ||: %__ln_s /bin/true /etc/init.d/cron fi %{fillup_and_insserv -y cron} %run_permissions %verifyscript %verify_permissions -e /etc/crontab -e /usr/bin/crontab %preun %stop_on_removal cron %postun %restart_on_update cron %insserv_cleanup %posttrans echo "posttrans of cronie" if [ -e /var/run/update_from_old_cron ]; then %{__rm} /var/run/update_from_old_cron ||: %__mv /etc/init.d/cron.bk /etc/init.d/cron ||: fi
Different behavior of rpm -U and zypper in
Lets imagine : you have installed cron-4.1 on system and you used snippets of spec above to build cronie-1.4.4 and supackage cron-4.2, then you call
rpm -U cron-4.2xx.rpm cronie-1.4.4.rpm
check the install stepszypper in cron-4.2xx.rpm cronie-1.4.4.rpm
check the install steps (same behavior also for zypper dup -r reponum), in this case zypper split process to two parts using rpm -U, this could be annoying because scriptlets are not executed in the same order, like in case of using pure rpm -U mentioned in previous point (to check what is zypper doing (during "zypper in cron-4.2xx.rpm cronie-1.4.4.rpm") I usedtail -f /var/log/zypper.log | grep "Executing 'rpm'"
) :
..(start_program):221 Executing 'rpm' '--root' '/' '--dbpath' '/var/lib/rpm' '-U' '--percent' '--force' '--nodeps' ... cron-4.2-242.1.x86_64.rpm' ..(start_program):221 Executing 'rpm' '--root' '/' '--dbpath' '/var/lib/rpm' '-U' '--percent' '--force' '--nodeps' ... cronie-1.4.4-242.1.x86_64.rpm'
rename process with modified spec using zypper in cron*.rpm
first process : zypper update cron from 4.1 to 4.2 using rpm -U --force --nodeps cron-4.2-xxx.rpm | |||||||||
Scriptlet from cron 4.2 package |
| ||||||||
---|---|---|---|---|---|---|---|---|---|
Scriptlets from cron 4.1 package |
| ||||||||
second process : zypper install cronie package using rpm -U --force --nodeps cronie-1.4.4-xxx.rpm | |||||||||
Scriptlets from cronie 1.4.4 package |
|
rename process with modified spec using rpm -U cron*.rpm
rpm -U runs in one process | |||||||
Scriptlet from cron 4.2 package |
| ||||||
---|---|---|---|---|---|---|---|
Scriptlet from cronie 1.4.4 package |
| ||||||
Scriptlets from cron 4.1 package |
| ||||||
Scriptlet from cronie 1.4.4 package |
|