Copy files in RPM spec files using micro %install - linux

I have problem with RPM spec file. I need to copy huge number of files located under tar.gz file:
%install
mkdir -p ${buildroot}/opt/agent
install -m 0755 -d $RPM_BUILD_ROOT/opt/agent
install -m 0777 * $RPM_BUILD_ROOT/opt/agent
The question is how I have to configure this micro to copy all files under /opt/agent into the new RPM file?

Related

Inconsistent results when installing .rpm package

I have a .sh script that I packaged as .rpm to distribute. I'm using GitLab CI CD pipeline using gitlab-ci.yml. I'm able to pacakge the script in .rpm with no problems using the .spec.
The issue is when I install the .rpm (after uploading and downloading) in various systems for testing and make sure it does what I expect it to do.
So in the .spec file I specify that I want to install it in /usr/bin/myscript.sh with the following in .spec file:
%build
%install
rm -rf %{buildroot}
mkdir -p $RPM_BUILD_ROOT/%{_prefix}/bin
install -m 755 -p $RPM_BUILD_DIR/myscript.sh $RPM_BUILD_ROOT/%{_prefix}/bin/
So to test the newly created .rpm I try to install in 2 different containers
First one called centos
Output
[root#1235 /]# curl -O http://url/srpms/myscript-1.0-1.el7.src.rpm
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5773 100 5773 0 0 626k 0 --:--:-- --:--:-- --:--:-- 626k
[root#1235 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var myscript-1.0-1.el7.src.rpm
[root#1235 /]# rpm -iv myscript-1.0-1.el7.src.rpm
myscript-1.0-1.el7.noarch
[root#1235 /]# rpm -ql xsoar*
myscript.sh
myscript.spec
[root#1235 /]# find . -type f -name "myscript.sh" 2>/dev/null
./root/rpmbuild/SOURCES/myscript.sh
[root#1235 /]#
As you can see the script ends up in a path that was created by the installation itself ./root/rpmbuild/SOURCES/ instead of the expected /usr/bin/
For the next container I used the same image/container used by gitlab-ci.yml to package the .rpm
Output
[root#5704de76a68c /]# rpm -iv myscript-1.0-1.el7.src.rpm
myscript-1.0-1.el7.noarch
[root#5704de76a68c /]# rpm -ql xsoar*
package myscript-1.0-1.el7.src.rpm is not installed
[root#5704de76a68c /]# find . -type f -name "myscript.sh" 2>/dev/null
./root/rpmbuild/SOURCES/myscript.sh
[root#5704de76a68c /]#
Similar result but it says .rpm is not installed
Then for the heck of I tried installing the .rpm in the same instance/container right after creation using gitlab-ci.yml (before it gets uploaded to any repo for distribution) and I do get the expected result
Output
$ rpm -ivh $HOME/rpmbuild/RPMS/noarch/*.rpm
Preparing... ########################################
Updating / installing...
myscript-1.0-1.el7 ########################################
$ rpm -ql myscript
/usr/bin/myscript.sh
Part of the .spec
%prep
cp -fp %{SOURCE0} ./
%build
%install
rm -rf %{buildroot}
mkdir -p $RPM_BUILD_ROOT/%{_prefix}/bin
install -m 755 -p $RPM_BUILD_DIR/myscript.sh $RPM_BUILD_ROOT/%{_prefix}/bin/
%clean
rm -rf %{buildroot}
%files
%attr(755,root,root) %{_prefix}/bin/myscript.sh
Found the issue. Of course it had to be stupid. For my testing i was installing myscript.src.rpm instead of myscript.noarch.rpm

rpminstall - run shell script inside rpm during install

I am working on an RPM which unpackages a tar file into an RPM whenever I run rpmbuild. I have two questions around the process:
Is my process of unpackaging the tar file into the RPM correct?
When I install the actual rpm onto a server, I'd like it to run a script inside the RPM which I have copied in called install.sh. How do I do that?
%build
# let's skip this for now
%install
mkdir -p %{buildroot}
chmod 755 ~/rpmbuild/SOURCES/bin/*
cp -frv ~/rpmbuild/SOURCES/bin/* %{buildroot}
%files
/*
%changelog
# let's skip this for now
Generally RPM support pre and post installation/uninstall scripts. And they are defined with %pre, %post, %preun and %postun. So if you are sure this file (install.sh) already exist you can run it on this way:
%pre
/path/to/install.sh
or
%post
/path/to/install.sh

How to install Python3.6.0 in centos automatically through shell scripts?

I know clearly how to install python3.6 in centos step by step.How can I do it automatically through shell scripts?
Through step-by-step methods, I use
tar -xvf python-file.tgz
./configure --prefix=/path/to/python3
make && make install
to install python3.6 successfully. What I want to do is to write these commands into a shell script and install it automatically.
My script is as follows:
#!/bin/bash
# creat folder if not exists. That folder if the directory of Python3 programs.
if [ ! -d /usr/python3 ];then
mkdir /usr/python3
else
echo "'/usr/python3' exists"
fi
DIR=`pwd`
# extract file from compressed file to tartget directory
tar -xvf Python-3.6.0.tgz -C /usr
# specify installation location
cd /usr/Python-3.6.0 && ./configure --prefix=/usr/python3
# make file and install
cd /usr/Python-3.6.0 && make && make install
# creat symlink
ln -s /usr/python3/bin/python3 /usr/bin/python3
ln -s /usr/python3/bin/pip3 /usr/bin/pip3
cd ${DIR}
pip3 install --no-index --find-links=./pkgs -r ./requirements.txt
It seems that this script isn't run line by line because /usr/python3 is empty, I want to know why.
Besides, I add && \ in each line except the last one, it seems works! I am really confused about it.

how to install nodejs 0.10.26 from binaries in Ubuntu

I am new to linux and am trying to install nodejs latest version with binaries. The solutions I have looked up suggest the installation using apt-get on some private repositories(PPA), which I do not want to do.
So I ran the following commands:
wget http://nodejs.org/dist/v0.10.26/node-v0.10.26-linux-x64.tar.gz
tar -zxvf node-v0.10.26-linux-x64.tar.gz
mv node-v0.10.26-linux-x64 node-v0.10.26
sudo cp -r node-v0.10.26 /usr/local/src
After this, I don't really know what to do. I read an article which suggested created symbolic links, which I am kind of scared to mess up with without knowing the details.
Could you please give me a set of commands to run after this in order to install node with npm? I guess npm should be a part of this binary version.
The best way to install Node.js and have the latest version (or any other version that you prefer, be it LTS or "current") is to download the official binary bundle and uncompress it. A neat way to do it:
# Use version 0.10.26
$ NODE_VERSION="v0.10.26"
# To use a newer version, for example 6.10.3, use instead:
$ NODE_VERSION="v6.10.3"
$ curl -LO http://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-x64.tar.gz
$ tar xzf node-$NODE_VERSION-linux-x64.tar.gz
$ sudo cp -rp node-$NODE_VERSION-linux-x64 /usr/local/
$ sudo ln -s /usr/local/node-$NODE_VERSION-linux-x64 /usr/local/node
The basic idea is to move all the contents of the archive into /usr/local, then create a symlink in /usr/local/node pointing to the most recent version.
For enabling the use of the "node" executable from the command line without referencing the full path (/usr/local/node/bin/node), add /usr/local/node/bin to your $PATH (usually this involves altering the ~/.bash_profile or ~/.profile file; there's plenty of docs for how to do this).
If you need to update Node.js (suppose it's version 7.10.0), then, just extract the tarball in /usr/local and update the symbolic link so it points to the new one. You can then optionally remove the old folder.
May 2017 update
As of the "Creators Update", the commands above can now work also on Windows 10 using the "Windows Subsystem for Linux" (via bash). On Ubuntu on Windows 10, after creating the symlink like above, to add the folder to your $PATH add PATH="/usr/local/node/bin:$PATH" in the ~/.bashrc file.
I combined both of these answers for my docker container. I wanted the executable to be in the PATH already without me explicitly doing that.
#!/usr/bin/env bash
install_node() {
NODE_VERSION="v8.3.0"
curl -# "http://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz" | tar -xz
cp -pr "node-${NODE_VERSION}-linux-x64" "/usr/local/"
ln -s "/usr/local/node-${NODE_VERSION}-linux-x64" "/usr/local/node"
ln -s /usr/local/node/bin/* "/usr/local/bin"
rm -rf "node-${NODE_VERSION}-linux-x64"
}
install_node
You can extract the binary anywhere and use update-alternatives command which maintain symbolic links determining default commands for example this is on my laptop.
first i extract my node node-v10.16.3-linux-x64.tar.xz on /mnt/e/WSL_Ubuntu/Downloads/node-v10.16.3-linux-x64/ folder :
xxxx#xxxxPC:.../WSL_Ubuntu/Downloads$ tar xvf node-v10.16.3-linux-x64.tar.xz
xxxx#xxxxPC:.../WSL_Ubuntu/Downloads$ cd node-v10.16.3-linux-x64/
then update-alternatives --install :
xxxx#xxxxPC:.../node-v10.16.3-linux-x64/bin$ sudo update-alternatives --install /home/wira/.local/bin/node node\
> /mnt/e/WSL_Ubuntu/Downloads/node-v10.16.3-linux-x64/bin/node 60
update-alternatives: using /mnt/e/WSL_Ubuntu/Downloads/node-v10.16.3-linux-x64/bin/node to provide /home/wira/.local/bin/node (node) in auto mode
Now i use the node on terminal
xxxx#xxxxPC:.../node-v10.16.3-linux-x64/bin$ node --version
v10.16.3
You should also update-alternatives --install on npm binaries.
I think there is still a cleaner way
NODE_VERSION="v6.7.0"
# Download
curl -LO http://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-x64.tar.gz
# uncompress
tar xzf node-$NODE_VERSION-linux-x64.tar.gz
# selective copy
cp -R ./node-$NODE_VERSION-linux-x64/bin/* /usr/local/bin
cp -R ./node-$NODE_VERSION-linux-x64/lib/* /usr/local/lib
cp -R ./node-$NODE_VERSION-linux-x64/include/* /usr/local/include
cp -R ./node-$NODE_VERSION-linux-x64/share/* /usr/local/share
Node should be working now
$ node -e 'console.log("HI")'
HI
Hope it helps

rpmbuild spec file %install section error

I have a spec file which is similar to:
BuildRoot: /tmp/build_%{name}-%{version}-%{release}
%prep
...
...
%install
# Directories
install -m 755 -d %{buildroot}/usr/app/mypackage/config
install -m 755 -d %{buildroot}/usr/app/mypackage/src
....
# Bash script
install -m 755 script/script1.sh %{buildroot}/usr/app/mypackage/config/script1.sh
install -m 755 script/script2.sh %{buildroot}/usr/app/mypackage/config/script2.sh
install -m 755 script/myapp-log %{buildroot}/etc/logrotate.d/myapp-log
When I run the rpmbuild I get the error:
install: cannot create regular file `/tmp/build_my_app-1.0-2/etc/logrotate.d/myapp-log'
I can get around this by manually creating the /etc/ and then /etc/logrotate.d directories in the /tmp/build_my_app-1.0-2/ directory.
When I re-reun the rpmbuild it will work.
I guess this is because I am not creating this directory in my install section but as its not directly related to my application I don't want to put that in.
My guess is that there is some clever tag I can use to fix this so that the build will work without any manual intervention.
My Question:
Could someone please suggest a way for me to achieve this (assuming its possible) or whether I need to write a script around the rpmbuild to set this up first.
You are missing the step to create the installation directories in your %install section. Remember that since you can build in "different" roots, you cannot expect certain directories (like ${buildroot}/etc) to be present.
Try adding
mkdir -p ${buildroot}/etc/logrotate.d
just before the install command that copies the file into ${buildroot}/etc/logrotate.d.

Resources