Issues while compiling a Go app from Windows to Linux - linux

My issue:
I need to compile a Go application from Windows (current workspace) to Linux (deployment environment), I've try several times using few techniques described in this platform and many more and nothing help, everything looks fine but isn't work.
I'm compiling for linux using this script in windows
$ set GOARCH=amd64
$ set GOOS=linux
$ go build app_name.go
in the cmd folder I can find a file named app_name with no extension, which should be fine.
Then, I receive an error when trying to execute the binary in Linux, using few ways
$ ./app_name
-bash: ./app_name: Permission denied
$ source app_name
-bash: source: app_name: cannot execute binary file
this is the file that I received after the compilation:
-rw-r--r-- 1 xxx xxx 7313830 Jan 26 16:59 app_name
If I run the application in windows with go run -arguments app_name.go it works perfect, but the issue appear after compile or try to compile the app for linux, I can't run the app even as root

On Unix systems, a file must have the executable bit set in order to be able to be run. This is the only way that the system knows what programs or scripts can be run, and differs from Windows, which uses extensions.
In this case, you need to change permissions by running chmod u+x unified_mapper before trying to execute it. If you want other users to execute it as well, you can do something like chmod 755 unified_mapper. Run man 1 chmod in the manual page to see more details about possible invocations.

Related

WSL2 distro shell can't launch a file copied from outside

The situation in short
I can't launch an executable (binary or a script) in a WSL2 distro if it wasn't created inside this distro
I can launch scripts and binaries that were created inside the distro shell (not using /mnt/c or /mnt/d in any way)
But I can't launch anything that was created outside and copied inside from Windows (using /mnt/c or /mnt/d)
I can see the copied files in the file system, can "cat" them, can look them up with "which", but I cannot launch them by entering the path into the command line
The questions I have in regards to all this
How come that the shell can't see the files while utils you run from the shell can?
How do I make the shell see files that were copied from outside?
If I can't make the shell launch the files, then how do I launch them?
The Situation in detail
I have Windows 10 with WSL2 and two distros
Ubuntu-20.04
Alpine
In Ubuntu I have a "Hello, World!" project written in C
It compiles in Ubuntu and then and runs in Ubuntu just fine
But, when I copy it from Ubuntu to Windows
cp hello /mnt/d/
and then go to Alpine and copy it inside from Windows
cp /mnt/d/hello .
I then have trouble launching it inside Alpine
Here is the output of file hello command in Ubuntu with some extra formatting (just in case)
$ file hello
hello:
ELF 64-bit LSB shared object,
x86-64,
version 1 (SYSV),
dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=021352ab7bf244e340c3c42ce34225b74baa6618,
for GNU/Linux 3.2.0,
not stripped
Here's what I have in Alpine
$ cp /mnt/d/hello .
$ ls -l
-rwxr-xr-x 1 pavel pavel 16760 Apr 19 19:07 hello
$ ./hello
-ash: ./hello: not found
Now same with a script copied from Windows
Copy the script inside Alpine from Windows
$ cp /mnt/d/hello.sh .
Checking the contents
$ cat hello.sh
#!/bin/ash
echo Hello!
Setting the execute permission just in case
$ chmod agu+x hello.sh
Trying to run it
$ ./hello.sh
-ash: ./hello.sh: not found
But, I can launch the hello.sh by explicitly calling the ash tool and passing the script path as the argument
$ ash ./hello.sh
Hello!
At the same time, a script created inside Alpine runs just by entering it's path to the command line
$ cat << EOF > hello-local.sh
> #!/bin/ash
> echo Local hello!
> EOF
$ chmod agu+x hello-local.sh
$ ./hello-local.sh
Local hello!
Also, I couldn't make a file that would run from one that wouldn't either by copying it with cp
cp hello.sh hello2.sh
or by copying it with cat
cat hello.sh > hello3.sh
cmod agu+x hello3.sh
Why do I need to copy things from outside
It all started when I wanted to explore how Docker for Windows uses Linux namespaces to separate containers
The distro that Docker for Windows uses is called docker-desktop
The docker-desktop distro neither has utilities that I need for my experiments, nor a package manager to get those utilities
So I tried to copy them from outside
But now Docker for Windows studies is not the only concern
I want to understand this magic that is happening just as bad
To be fair, there really are three separate questions here, but not necessarily the questions you listed in your post:
Secondary question -- Why does your script that you copied to Alpine fail?
As #MarkPlotnick covered in the comments (and you confirmed), it was due to the script having DOS/Windows line endings (CRLF). In general, try to avoid creating or editing Linux text files using Windows tools unless you are sure that they are using Linux line-endings.
Secondary question -- Why does your C program fail when you compile on Ubuntu and copy the binary to Alpine?
Also as #MarkPlotnick mentioned in the comments, this is because Ubuntu uses glibc as the standard library implementation by default, but Alpine uses musl. See a number of questions here for more information. The first one in the list sorted by "relevance" is actually a pretty good one to start with.
Main question -- How to explore the docker-desktop distro
Really, your main goal seems to be how to gain access to certain tools inside the docker-desktop distro in order to learn more about it.
I was going to say, "don't" (with more explanation), but the reality is that I think it's a potentially good learning experience. I've done it, to some degree, so who am I to say it's "too dangerous" or recommend against it? ;-)
I will give fair warning, though -- The docker-desktop distro isn't intended to be run by users. Docker Desktop "injects" links and sockets into your other WSL2 distros (which you can enable/disable per-distro in Docker Desktop) so that its tools, processes, etc., are available to all your WSL2 (and PowerShell/CMD) instances.
I'd personally try to avoid making any changes to the docker-desktop distro itself. They'll likely be overwritten anyway by Docker Desktop when it extracts a new rootfs.
However, we can still gain access to the tools we need by accessing them from another distribution, but without copying them into docker-desktop.
First, a note -- As I think you have probably already figured out,docker-desktop is also musl-basesd. So you'll want to use tools from another musl-based distro like Alpine.
This can be easily accomplished by running the following line once in your Alpine instance (as root):
echo "/ /mnt/wsl/instances/Alpine none defaults,bind,X-mount.mkdir 0 0" >> /etc/fstab
That will add a mount to the Alpine instance into the tmpfs /mnt/wsl mount. You can see my Super User answer here for more details on that.
Once you wsl --terminate Alpine and restart it, you'll have access to the Alpine files from any other WSL2 distribution.
As a useful (for your intent) example, install the util-linux package in Alpine to get access to the lsns command.
Then, in the docker-desktop distro (which I assume you already know to access with wsl -u root -d docker-desktop, but I'll include that command here for other future readers), to list the namespaces:
/mnt/host/wsl/instances/Alpine/usr/bin/lsns
The docker-desktop instance automounts at a slightly different directory than default (see cat /etc/wsl.conf), so you need to adjust the path to /mnt/host/wsl instead of /mnt/wsl.
But with that in place, you can run all (most?) of your Alpine binaries directly in docker-desktop without having to modify it directly. If you have a script in your home directory that you want to run in docker-desktop, for instance:
/mnt/host/wsl/instances/Alpine/home/users/<yourusername>/hello.sh
Note that if you have a binary that requires a dynamically-linked library on Alpine, I'm assuming you'll need to adjust your LD_LIBRARY_PATH accordingly, although I haven't tested. For instance:
LD_LIBRARY_PATH=/mnt/host/wsl/instances/Alpine/usr/lib /mnt/host/wsl/intances/Alpine/usr/bin/<whatever>

Opening AppImage does nothing. What can I do?

I am a complete newbie to Linux and trying to open an AppImage called Magick which is an Imagemagick application.
I tried right clicking on the AppImage and checked "run file as an executable" option but that didn't work. Another thing that I tried is running this command,
chmod a+x magick.AppImage
This gives me an error,
chmod: cannot access 'magick.AppImage': No such file or directory
I have also tried running the file by navigating into the folder that contains the file and opening up the terminal there but still no luck.
I am running Ubuntu on Oracle VM VirtualBox.
ImageMagick is a command-line tool, you don't run it by clicking on it.
To run it in a terminal you need to
Set the executable flag on the .AppImage (once for all): chmod +x TheApp.AppImage
Then to run it just invoke the AppImage: ./TheApp.AppImage <arg1> <arg2> ....
If the directory with your .AppImage is in your PATH, you can remove the ./ (or whatever directory the AppImage is in).
ImageMagick is also available as a regular application from your Ubuntu repository: sudo apt install imagemagick

OpenShift oc command line with Cygwin

I'm running Cygwin 64bit but can't seem to get OpenShift oc command line to work
I downloaded oc.tar.gz ( from here https://mirror.openshift.com/pub/openshift-v3/clients/3.6.173.0.5/linux/oc.tar.gz ), unzipped it and placed it in my path in /usr/bin
When I try to run: oc login I get the following.
-bash: /usr/bin/oc: cannot execute binary file: Exec format error
Do I need to somehow 'install' the executable ?
Any help would be much appreciated.
In addition to #Graham Dumpleton's answer:
open cygwin and check for directory /usr/local/bin
mkdir -p local/bin
$ cd /usr/local/bin
if it does not exists:
$ mkdir -p local/bin
finally extract the windows package:
$ cp /cygdrive/c/Users/me/Downloads/oc-3.5.5.31.24-windows.zip /usr/local/bin/
unzip oc-3.5.5.31.24-windows.zip
$ oc version
oc v3.5.5.31.24
kubernetes v1.5.2+43a9be4
features: Basic-Auth
Use the Windows binary from the following page:
https://github.com/openshift/origin/releases
From project homepage
https://www.cygwin.com/
Cygwin is not:
a way to run native Linux apps on Windows. You must rebuild your
application from source if you want it to run on Windows.
a way to magically make native Windows apps aware of UNIX®
functionality like signals, ptys, etc. Again, you need to build your
apps from source if you want to take advantage of Cygwin
functionality.

Can't launch sonar 2.8 (permission denied to execute wrapper )

I'm new to Sonar, and i was trying to install Sonar 2.8 on my server (Linux 64 on HP-UX)
When i tried to launch it (sonar.sh start) i got the following message
[myHomeDirectory]/sonar/2.8/bin/linux-x86-64/./wrapper: Execute permission denied.
what drives me crazy is that i've putthe whole package on 777 permissions, so i really don't understand what's exactly happening.
Can anyone help with this please ?
Thanks in advance !
I hit a similar issue hence why I came to this post. I was attempting to install SonarQube's scanner in a Docker container but when I was running it, I was getting something along the lines of:
/root/sonar-scanner-2.6.1/bin//sonar-scanner: 103: exec: : Permission denied
I had given the whole /root/ folder all permissions so I was curious about the permission denied. In the end for me it wasn't anything to do with permissions. I simply needed to RTFM.
Sonar-scanner needs a JRE to run and my Docker container didn't have one installed. So if anyone else does the same thing as me, I hope this saves you a few minutes of head scratching.
Not really convinced in the way you are launching it. To get Sonar running I recommend running it on tomcat, providing you just want to use the default database that comes with Sonar. The steps would be:
Install Tomcat
Navigate to your /war directory within your sonar instance and run the command: $] ./build-war.sh.
When this finishes you should see a sonar.war file in the same directory.
Rename the war file ROOT.war instead of sonar.war: $] mv sonar.war ROOT.war
This ensures that sonar runs on tomcat's default port.
Move the war file into the tomcat webapps directory: $] mv ROOT.war /tomcathome/webapps
Navigate to the tomcat /bin folder and run the command $] ./catalina.sh start
Type your server hostname in your browser with a port :8080 at the end and you should see sonar running.
These steps will have sonar running on the default database, though. If you want a MySQL database i'd look at sonar tutorials on how to do that.
I finally came out with the conclusion that the binary file (wrapper) is simply not compiled to run under HP-UX
when launching a file command on wrapper under a Linux i get : <ELF-64 executable object file> which doesn't match the <ELF-64 executable object file - IA64> required by HP-UX running on a Itanium processor
Please check if you have java installed on the machine. Java should be installed on the machine before running sonar-runner.
Use this to check java : java -version

Tomcat deploy: make included scripts executable

I'm devellopping a WebApplication (for Tomcat) using netbeans on Windows 7. For the Webapplication to run I need to run a insall-script once.
This script (*.bat for windows and *.sh for linux is included in my war-file (WEB_INF).
Now everytime I deploy the WAR-file and want to run the script on linux I have to call
chmod +x install.sh
first.
Is there a way that this script can be made executable by default? I don't want to have to execute some extra commands after the deploy to make the script executable.
For clarification:
I'm not new to Linux and I know how to set executable-rights on files. That's not the problem. My problem is: What do I have to do, so that this script is executable right after tomcat deployed my *.war-file (unpacked it). If I would be using Linux for development as well, I would try to set the rights according in my sources (maybe I'll try it when I have a little more spare time). But I am using Windows and netbeans.
Are there any attributes I can set to achive my goal, or is it possible to achive this using ant?
By the way: Are there security related issues with this approach? The script looks for java executable and calls a javabased GUI-installer...
Change permissions during initialization of the application, the following:
String [] command = {"/bin/chmod","+x",full_path_to_install.sh};
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec( command );
pr.waitFor();
allows your application to set executable permissions before using the script. It is not executable right after tomcat deployed your war file but just before your application uses it.
Assuming you are invoking the same "install.sh" everytime, you need to set the execute bit only once. Also, the executable bit need to be set only for the user (the command you have provided will set it for everyone).
chmod u+x install.sh

Resources