Change file members when creating RPM updates - rpmbuild

Our application has been packaged into a single rpm file for the past few years with the usual numbered updates. Now I'd like to separate out some of the files into a second RPM for product management purposes.
Is the correct way to just remove the files from the %files section of the old .spec file and add them to the new .spec file?
For example, we now have myApp.rpm built from:
/usr/local/myApp
+ bin/ {bunch of files here}
+ config/ {bunch of files here}
+ branding/
So the current spec file lists everything above in its %files directive.
To split branding into a separate rpm without messing up packaging? eg.
myApp.spec
Name: myApp
%install
{make directories, copy everything but branding}
%files
/%{_prefix}/myApp
/%{_prefix}/myApp/bin/*
/%{_prefix}/myApp/config/*
and
branding.spec
Name: myApp_branding
Requires: myApp
%install
{copy branding to rpm tree}
%files
/%{_prefix}/myApp/branding/*
When existing installations are upgraded, will the package membership of the branding files be now be the myApp_branding package?
Any downsides or risks to this approach?
Thanks

No, this is not recommended way.
Remember only one .spec file is enough for each project, you can use %package body item for additional rpm packages. for example add following code after meta information. i.e before %prep or %build items
%package branding
Summary: Branding for myApp
Requires: myApp
%description branding
branding files for myApp
After that, yes you can use multiple '%files' section for each package. like
%files
/%{_prefix}/myApp/bin/*
/%{_prefix}/myApp/config/*
%files branding
/%{_prefix}/myApp/branding/*
As you can see I have omitted /%{_prefix}/myApp line from main %files section. Actually when you pick a parent directory it automatically includes all its children, And when a sub package try to include child directory again, it will result in duplication error at build time. If you want to use /%{_prefix}/myApp then %exclude can help. see
%files
/%{_prefix}/myApp/*
%exclude /%{_prefix}/myApp/branding/*
%files branding
/%{_prefix}/myApp/branding/*

Related

Why use %files directive in RPM spec file and how to automate file listing in that section?

Why does %files needed and why it cannot be created automatically by listing $RPM_BUILD_ROOT directory contents?
For example, in that spec file i have to use some modifications in it in script, that build an RPM package for me. I have to cd into ~/RPM/SOURCES, then find . in it and echo each line into .spec file to setup %files section. It can be done automatically by the tool using the same techniuque i do in the background but from $RPM_BUILD_ROOT directory instead?
%install
mkdir -p $RPM_BUILD_ROOT/opt/MyCompany/MyProduct/
cp -rf -- ~/RPM/SOURCES/* $RPM_BUILD_ROOT/opt/MyCompany/MyProduct/
%files
/opt/MyCompany/MyProduct/file_1
/opt/MyCompany/MyProduct/file_2
/opt/MyCompany/MyProduct/file_3
... - a lot of lines here
/opt/MyCompany/MyProduct/file_100000
UPD:
Yes it is possible to use all copied files automatically (Doc http://ftp.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html)
In my case %files can be rewritten as that
%files
/opt/MyCompany/MyProduct/*
It will take files from $RPM_BUILD_ROOT/opt/MyCompany/MyProduct, so to use star we need to omit build root which is $RPM_BUILD_ROOT or %{buildroot} (Which is default path where rpm searches for files IIUC)
Why does %files needed and why it cannot be created automatically by listing
$RPM_BUILD_ROOT directory contents?
It is common that one spec file build creates multiple (sub)packages - then also
multiple %files sections are needed.
Even though there exist some automatic %files
section
generators,
nb there's the
%files -f option,
in general it isn't possible to split the files automatically.
Worth saying that most of the package maintainers don't maintain the software
source code, but just package the "upstream" releases. If the %files sections
are rather manually maintained (in contrast with the wildcard patterns), the
package maintainer has everything a bit more under control because he is
notified about the changes in the software installation layout (e.g. when a new
file appears in /usr/bin with a new release, rpmbuild starts complaining that
there's a new "unpackaged" file, see below).
It can be done automatically by the tool using the same techniuque i do in the
background but from $RPM_BUILD_ROOT directory instead?
You don't even have to run find manually. As long as %install creates the
files in $RPM_BUILD_ROOT, if you don't mention them in %files - you get reports
like those:
$ rpmbuild -bb *.spec
...
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/user/rpmbuild/BUILDROOT/test-1-1.x86_64
error: Installed (but unpackaged) file(s) found:
/usr/bin/not-packaged
RPM build errors:
Installed (but unpackaged) file(s) found:
/usr/bin/not-packaged

rpm subpackages %install section

Is it possible to have a separate %install section for a subpackage in a spec file?
For example, files can be specified for the main package as
%files
and for the subpackage like this:
%files mysubpackage
however, I have only seen one
%install
section, and I get an error if I do
%install mysubpackage
no, you cannot have, and you don't need a separate %install section.
Let's suppose a typical example: you compile a program and want to create two packages; library.rpm and library-devel.rpm (with the headers). Then you'll have a spec file something like this:
Name: library
# probably some other fields...
%description
describre library
%package devel
Summary: headers for library
%description devel
describe library-devel package
%prep
# some common prep code for both packages; eg
%setup -q
%build
make (or whatever to build your program)
%install
# install files for both rpm packages; library AND headers
mkdir -p ${RPM_BUILD_ROOT}/%_libdir/
mkdir -p ${RPM_BUILD_ROOT}/usr/include/
cp library.so* ${RPM_BUILD_ROOT}/%_libdir/
cp include/*.h* ${RPM_BUILD_ROOT}/usr/include/
%files
%defattr(-,root,root)
%_libdir/*.so.*
%files devel
%defattr(-,root,root)
%_libdir/*.so # yes; if you use version numbers; the versioned .so go in the normal package; the one without version number in the devel package
/usr/include/*
further reading: RPM packaging guide

How to share/transfer an Atom installation (packages and settings) from one Mac to another?

Is it possible to copy Atom from one Mac to another, including all installed packages, settings etc?
There are several ways to synchronize your settings and packages between Atom installations:
Git: Create a public or private Git repo and store the contents of your local ~/.atom folder in there. Ignore the following files/directories in a .gitignore file:
storage
compile-cache
dev
.npm
.node-gyp
Use a package like sync-settings. This will store your configuration in a GitHub Gist.
Dropbox (or similar): Move your ~/.atom folder to your Dropbox folder and then symlink it from there to its original location. This has the downside of syncing everything in ~/.atom, even the things you could ignore.
Use stars to select your favorite packages. On the Atom web site, create an account and mark your favorite packages with stars. Then use apm stars --install to install all starred packages on any machine. Downside: This only works for packages, not for settings.
More details:
https://discuss.atom.io/t/syncing-settings-packages-between-machines/1385
As a user who uses a dotfile management system such as RCM, I prefer independent config files.
For now, Atom doesn't officially provide a packages.cson file to manage plugins, but as the post Syncing settings & packages between machines mentioned, there is a plugin called package-sync that will generate a packages.cson file for us.
So with the help of package-sync, now I can just sync those mininal config files to have my Atom settings and packages consistent across multiple machines.
This is how to do it (Use ubuntu as an example):
Install Atom, and install package-sync through Edit-->Preferences-->Install as the screen shot shows:
Open your command pallete and type: Create Package List and there will be a packages.cson file under your ~/.atom folder.
Edit the gitignore file:
$ gedit ~/.atom/.gitignore
Make sure the content is:
blob-store
compile-cache
dev
storage
.node-gyp
.npm
.apm
packages/
atom-shell/
This is a screenshot of the .gitignore file:
This makes sure the content downloaded by Atom from the Internet will not get synced to your dotfiles repo.
Move the .atom folder to the dotfile repo:
$ mv ~/.atom ~/dotfiles/tag-atom/atom
Relink the folder:
$ ln -s ~/dotfiles/tag-atom/atom ~/.atom
Or if you have rcm installed:
$ rcup
Now go to another machine, and install Atom and package sync. Update your dotfiles repo, and then Open your Atom command pallete and type: sync
Now your Atom settings will get synced and integrated with the RCM dotilfe management system.
This is the files in my ~/.atom folder that get synced:
I recently built a package that syncs automatically your Atom settings and packages across multiple computers. A little bit like the bookmark synchronization mechanism in Google Chrome. It's called atom-package-sync. Maybe it could fit your needs.
You can sync your packages via package-list.txt file and a simple shell script.
Create the package-list.txt file
apm list --installed --bare > package-list.txt
Install missing packages on another host
BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALLEd_PKGS=$(apm list --installed --bare)
for PKG in $(cut -f1 -d# $BASEDIR/package-list.txt); do
grep -q $PKG <<< $INSTALLEd_PKGS || apm install $PKG
done
The .atom folder contains the packages folder, which can be rather huge. Unfortunately OneDrive doesn't allow you to exclude folders, so I went with a git option.
I excluded the packages from git and instead I committed a text file containing my packages (my-packages.txt).
To re-install packages I need to run: apm install --packages-file my-packages.txt.
To generate the my-packages.txt, I need something like this on a Bash shell: ls packages | xargs -n 1 echo | cut -d/ -f1 > my-packages.txt
I sync my Atom settings between Windows, macOS, and Linux machines using Resilio Sync Home. It is free and the files are not saved on the "cloud" (like Dropbox or Gists), but it requires that, at least, two machines are online in order to sync the current settings.
I do not want to sync caches, installation specific settings, et al., I update the .sync/IgnoreList file that is created in the synced directory (i.e., the ~/.atom directory). Unfortunately, you will have to update this on each machine that you sync (ironically, the IgnoreList file is not synced). By default, the file specifies various temporary files to be omitted from syncing, so you'll need to add the following:
## Atom-specific
/packages/node-debugger/debugger.log
\packages\node-debugger\debugger.log
/.apm
\.apm
/.node-gyp
\.node-gyp
/.npm
\.npm
/blob-store
\blob-store
/compile-cache
\compile-cache
/dev
\dev
/recovery
\recovery
/split-diff
\split-diff
/storage
\storage
Some of the omitted directories are package-specific (e.g., split-diff). Because Windows has different path delimiters than other platforms, I need to specify both(!!)
Install Resilio Sync Home on your first machine
Add the .atom directory to Resilio to be synced.
Update its IgnoreList file, as shown above. Save this file for the other machines you want to sync with.
Send a Resilio "Read & Write" link of that folder to the other machines you want to sync with or copy the "Read & Write" key to be used on the other machines. To do this, in Resilio's folder view, click on the .atom folder's menu (vertical dots on the right edge) and select "Copy Read & Write key". Save it for later.
Then on your other machines,
Install Resilio Sync Home
Create .atom/.sync
Copy the IgnoreList from your first machine to that directory
Add the .atom directory to be synced with the other machine. You should add the folder using "Enter key or link," then enter the key you copyed, above.
Wait until syncing is done before opening Atom. The first time will may take a few minutes.
Now I don't need to go around installing/removing packages on every machine, separately!
FYI: Changes to files and directories are saved in .sync/Archive, for some period of time, if you should need to recover them.

How to add files in the RPM package of an Sailfish OS project?

I am trying to build a Sailfish OS app, and I need to use *.wav files, which are to be distributed through the *.rpm package. In my case, these files are to be put in /usr/share/[application_name]/sounds/*. How do I set up the *.pro and *.yamp files accordingly?
This isn't a RPM question per se: you seem to be asking how to configure
your application through *.pro and *.yamp if you deliver content in
*.rpm packages.
The packaging answer is: Patch the configuration files exactly the same
as if you were installing the *.wav files manually (i.e. not through *.rpm).
You will need to copy the *.wav content into the %buildroot tree that
is used to stage the files to be included in the package, as well as the
modified *.pro and *.yamp content. All the files to be included in the
*.rpm package will need to be mentioned in the %files manifest exactly
as they are to be installed (i.e. w/o the %buildroot prefix used for
staging files while building).
I finally found an answer!
I want to thank to the owner of that project:
https://github.com/krig/metronom-sailfish
From the .pro and the .yaml files of this project i found out how to deploy the files. First, we declare that constant:DEPLOYMENT_PATH = /usr/share/$${TARGET} which seems to hold the path to /usr/share/[appname]. Next, we define some kind of a variable (TODO: find a more detailed explanation of that). The definition of that first sets the path to the files, for example, data.files = data (the second data is the folder). Next, we set data.path to $${DEPLOYMENT_PATH}. We list all the files in OTHER_FILES and add the setting, in our case, data, to INSTALLS. Now, that we are finished with the .pro file, we move to the .yaml file for the .rpm and we add to the necessary line to the Files: section, in our case, - '%{_datadir}/%{name}/data', the last being the folder we need to add. TODO: to whoever is more experienced, please provide a more detailed answer.
Did you check https://sailfishos.org/develop-packaging-apps.html carefully? May helps.

Installing an empty directory with RPM

In my install section of my rpm Spec file I have a bunch of mkdir's to create the directories I need. The ones that don't have any files installed in them get pruned out in the end and don't end up getting created. How can I ensure that the empty directories get created when it is all said and done?
In your %files section:
%files
%dir /my/directory/name

Resources