how to update a pre-existing config file using rpmbuild? - linux

I've been looking into how to use an rpmbuild spec file to update an already existing config file.
As an example, in my rpm I'd like to add lines to a config file e.g. /etc/stunnel/stunnel
[SomeAppName]
accept = 8006
connect = 127.0.0.1:5006
I've currently got this in my %install section:
cat stunnel/stunnel.conf >> %{buildroot}/etc/stunnel/stunnel.conf
Now clearly this is rubbish because each time I run the rpm it will add these same lines to the config file.
I also don't want the /etc/stunnel/stunnel.conf file to be part of my rpm as I don't want it removed when I erase my rpm package.
My questions are:
How can I exclude the /etc/stunnel/stunnel.conf from being part of my rpm?
What is the correct way to add lines to a config file during an rpm?
Please could someone provide some links where I can see how to get this working or example of a few lines that I can use in my spec file.
I've look at the official guide over at Max Rpm but so far I've not found the answer to my issue.

a) Many more modern tools also support a .d configuration directory parallel to flat files for this exact reason. For example, my Debian wheezy distribution treats /etc/stunnel as a directory in which each .conf file is a separate stunnel configuration.
b) The established alternative seems to be a conditional construct like
grep -q '[SomeAppName]' %{buildroot}/etc/stunnel/stunnel.conf || cat ...
(or, if not sure if stunnel.conf already exists)
grep -s '[SomeAppName]' %{buildroot}/etc/stunnel/stunnel.conf || cat ...

Related

How do I mark a file as config(missingok) in fpm non-interactively?

I've been trying to use fpm to create an rpm, but have ran into a problem. After I install the package, there are files I no longer need which are deleted in a post-install script in order to save space. Unfortunately, when the packages in uninstalled, it complains about the files not being there, as they are still registered by the rpm as part of the package. When I looked into how to fix this via the rpm, I stumbled on the %config(missingok) macro which seems ideal. However, it doesn't seem like there is a way to set this via fpm.
My current options for possible solutions are changing the -edit flag from using vi to edit the spec file to using a script by setting the fpm_editor variable, or touching the file in a pre-remove script to try and trick the rpm into thinking these problematic file still exist. Neither of these option are very appealing.
So my question is this: Is there a way to use fpm to either a: remove the package from the "sight" of the rpm post-install, or b: mark the file as noconfig(missingok) via fpm?
Without utilizing the two solutions above of course.
The usual way of doing this is rm -f these files at the end of the %install section, instead of doing this in the post-install scriptlet.
This way the useless files will not be packaged in the final rpm.
I never packaged an rpm with fpm, but looking at the source code I see the command-line switches --exclude and --exclude-file that should be the ones you're looking for:
option ["-x", "--exclude"], "EXCLUDE_PATTERN",
"Exclude paths matching pattern (shell wildcard globs valid here). " \
"If you have multiple file patterns to exclude, specify this flag " \
"multiple times.", :attribute_name => :excludes do |val|
excludes << val
next excludes
end # -x / --exclude
option "--exclude-file", "EXCLUDE_PATH",
"The path to a file containing a newline-sparated list of "\
"patterns to exclude from input."

remove entries from PATH while uninstalling rpm

To leave the system in a cleaner state, I am trying to remove entries from the PATH in the %preun section of my rpm spec file.
I found couple of threads on stackoverflow that I tried
What is the most elegant way to remove a path from the $PATH variable in Bash?
AND
Linux: Remove path from $PATH variable
Answers in both these links work perfectly when I manually run them on a terminal.
But, they don't work when I run the rpm -e xx command.
If my PATH looked like this after successful installation:
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/lpp/mmfs/bin
and I am trying to remove /usr/lpp/mmfs/bin,
After the rpm uninstall the PATH looks like:
/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin
Questions:
1) Do I need to do something different when the commands mentioned in the earlier links are run from the spec file?
2) What are some recommended ways to remove PATH entries during rpm uninstalls?
Note
Commands I have tried in spec file are:
PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')
and
PATH=${PATH/:\/home\/user\/bin/}
The RPM %preun script cannot affect the PATH variable of any running shells. That isn't possible.
It can't (directly) affect the PATH variable of any new shells either.
The only thing it can do is remove whatever changes it made to the system (or user shudder) shell startup files that caused the PATH variable additions to be made.
Removing those changes will cause any new shells not to have those changes made and therefore not to have those additional PATH entries in them.
The proper way of adding to a PATH (and subsequently, removing it later), would be to drop a file yourpackage.sh and yourpackage.csh in /etc/profile.d.
I also agree with others that it's probably a bad idea, but if you need to do it, that's how I would.

wget Downloading and replacing file only if target is newer than source

This is what I'm trying to achieve :
User uploads file1.jpg to Server A
Using wget Server B only downloads file1.jpg from Server A if the file is newer than the one that already exists on Server B and then replaces the file on Server B with the new one.
I know I can use :
wget -N http://www.mywebsite.com/files/file1.jpg
To check that the target file is newer than the source but I'm a little confused as to how I format the command to let it know what and where the actual source file is?
Is it something like? :
wget -N http://www.mywebsite.com/files/file1.jpg /serverb/files/file1.jpg
Cheers!
You can use -P option to specify the directory where the file(s) will be downloaded:
$ wget -N -P /serverb/files/ http://www.mywebsite.com/files/file1.jpg
You are also talking about downloading and replacing the file. Be aware, that wget overwrites the file, so it is "broken" while being downloaded. I don't think you can do atomic replacement of the file using only wget. You need a small script that uses temporary files and move to atomically replace the file in Server B.

Simple Linux command line command to modify an option in a INI-like config file

I am looking for a generic command line solution that would allow me to add or modify a configuration option inside a config file (INI-like format).
Most Linux configuration files use a INI-like format, with # and ; as comment and with option=value.
Mainly I am looking for something that would take filename, option and value, and that will change the config to match this.
I want to use this to write some auto-deployment scripts. I have no problem on using tools that are not installed by default on Debian or Ubuntu as long they do exist in the default distribution repositories (as I can do an apt-get install xxx, if needed).
Example: change-config /etc/default/nginx ULIMIT '"-n 4096"'
The expected result would be to have ULIMIT="-n 4096" inside the nginx file. Obviously if it does already exists and have the same value, it should do nothing. If it exists, commenting the old line would be fine and adding the new one.
As a note, these config files can have spaces/tabs between parameters so if you have ULIMIT = "..." is still the same command. That's why I was looking for something better than sed as there are plenty of corner cases to evaluate.
Also, I don't want to reinvent the wheel, and I doubt that I am the first one to look for a solution to this kind of problem.
git config is actually a semi-generic INI interface.
❱ git config --file=/etc/default/nginx somegroup.ULIMIT '-n 4096'
❱ cat /etc/default/nginx
[somegroup]
ULIMIT = -n 4096
❱ git config --file=/etc/default/nginx somegroup.ULIMIT
"-n 4096"
It doesn't support adding top-level keys, though. All keys have to be placed in an INI style group, hence the "somegroup." above. That makes it unsuitable for your task, but I thought I'd mention it here for others finding their way here.
Try crudini. BTW I think this file is a shell file rather than an ini file,
but crudini can still work in this case:
crudini --set /etc/default/nginx '' ULIMIT '"-n 4096"'
Augeas / augtool aims to do this, although you'll need the right lens for the type of file you're after (you can also write your own), for example, the Nginx lens.
It also has an API if required.

Moving .ghc and .cabal to a different user

How can I move the GHC and cabal installed packages to a different user? I've copied the directories but I'm getting error messages like:
ConfigParser.hs:15:8:
Could not find module `Data.ByteString.Char8'
There are files missing in the `bytestring-0.10.2.0' package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
ghc-pkg check shows that any file for any package is missing. How can I resolve this?
Note: This question intentionally does not show research effort, because it was answered Q&A-style.
First, you obviously need to copy .ghc and .cabal. These contain the binary files and configurations.
For simplicity, we will assume moving from user foo to user bar. Note that moving between architectures is not possible, as the binaries produced by GHC are not platform-independent.
After copying the aforementioned directories, there are paths like /home/foo remaining in different locations. We will use sed to replace those (run this as bar):
sed -i -e "s/foo/bar/g" ~/.cabal/config
sed -i -e "s/foo/bar/g" ~/.ghc/*-*/package.conf.d/*.conf
However, the file ~/.ghc/*-*/package.conf.d/package.cache still contains file references containing the username. We can't simply use sed to replace, however, because it's a binary file and it might destroy the package cache.
You can use ghc-pkg recache --user to re-cache all packages.
After performing these steps, you should be able to use the cabal packages as expected.

Resources