I am building an image with Dockerfile. I am pulling latest Ubuntu and golang images.
After importing all the directories and building the executable with go build inside the image, I want to run the executable. For that reason, I tried using either ENTRYPOINT or CMD, so that the executable runs when the container starts.
The issue is that when I do that and I am running the container in either attached or detached mode, it keeps registering the Enter Key repeatedly all the time (and CPU usage goes crazy). I can understand this because my script waits for a key to be registered and then some input to terminate, but since the Enter key is registered immediately again, it prints a message and then the same loop happens again.
When I build my image without executing (no CMD or ENTRYPOINT) the binary, I then run the container (the binary is still built inside the image) with a bash terminal and I execute the binary and all goes normal as it should, without any Enter Key registering all the time.
Any ideas why this might be happening???
Brief description of my Dockerfile:
# Import Images
FROM ubuntu:18.04
FROM golang:1.10
# Open ports
EXPORT ...
# Copy dependencies to GOPATH in docker file
COPY github.com/user/dependencies /go/src/github.com/user/dependencies
...
# Set working directory and build executable
WORKDIR /go/src/github.com/user/app-folder
RUN go build
# Run the binary (or not)
CMD ["app_name"]
-----OR-----
CMD ["./app_name"]
-----OR-----
ENTRYPOINT app_name
-----OR-----
ENTRYPOINT /go/src/github.com/user/app-folder/app_name
In the end, I tried all these, one at a time, I just included them like this for display. The result was always the same. The result in the terminal is:
...
Are you sure you want to exit? y/n
running. press enter to stop.
Are you sure you want to exit? y/n
running. press enter to stop.
...
The go script is as follows:
// running flag is set to True and then it scans for a newline
for running {
fmt.Println("running. press enter to stop.")
fmt.Scanln()
fmt.Println("Are you sure you want to exit? y/n")
if models.ConfirmUserAction() {
running = false
close(models.DbBuffer)
}
}
and the models package that includes the ConfirmUserAction function:
//ConfirmUserAction waits (blocks) for user input, returns true if input was Y/y, else false.
func ConfirmUserAction() bool {
var confirm string
fmt.Scanln(&confirm)
if confirm == "y" || confirm == "Y" {
return true
}
return false
}
I found a way to bypass this issue by creating a shell script inside the container, which then runs the executable (maybe a bit hacky way, but the Enter Key is not registering any more all the time).
So now, instead of running the executable at the ENTRYPOINT on my Dockerfile, I am running the shell script at the ENTRYPOINT which simply includes something like this:
#! /bin/sh
sleep 1;
echo "Starting Metrics Server..."
./metrics_server
The metrics_server is my compiled executable and I am setting the working directory WORKDIR, inside my Dockerfile to be were the executable and the shell script are.
Something worth mentioning about this, is that I already have imported the Ubuntu image in my Dockerfile (FROM ubuntu:18.04), as I need it anyways. I am saying this because it might not work without it (not entirely sure, I did not try it).
Related
I am trying to install confluent kafka on my databrick drivers and using init scripts there.
I am using below command to write an script to DBFS like below:
%python
dbutils.fs.put("dbfs:/databricks/tmp/sample_n8.sh",
"""
#!/bin/bash
wget -P /dbfs/databricks/tmp/tmp1 http://packages.confluent.io/archive/1.0/confluent-1.0.1-2.10.4.zip
cd /dbfs/databricks/tmp/tmp1
unzip confluent-1.0.1-2.10.4.zip
cd confluent-1.0.1
./bin/zookeeper-server-start ./etc/kafka/zookeeper.properties &
exit 0
""")
The I edit my intiscripts and add en entry there to denote to above location
[![init scripts entry adding][1]][1]
However, when I try to run my cluster it nevers starts and it always halts. If I go to event log, it shows that it is stuck at 'Starting init scripts execution.'
I know there should be tweak in my script to run it on the background but even I am using & at the end of the start command for zookeper.
Can someone give me any hint how to resolve above?
[1]: https://i.stack.imgur.com/CncIL.png
EDIT: I guess this question could be the same if I ask how I can run my script in a %sh databricks cell while the cell can finish the running of above bash script, but at the moment it always telling me that the command is running
I'm trying to write a shell script that will attempt to build a Docker-Compose image, then if that's successful, start up the Docker container with it by doing a Docker-Compose up -d.
In the second step, I load some JSON files into Mongo, but then if there's a problem with that step, I want want to stop all Docker services and print out an error message saying "Could not start Docker service because there was a problem seeding the DB."
My problem is that I don't know how to check if the image was created successfully in the first step. (I want to stop and print out a message saying that there were errors in the build.)
I think I can figure out something that checks if both services are running at the end, but I'm wondering if there is a way to print out the name of the problematic JSON file that couldn't load.
Does anyone have a similar script that I can use or modify for my own use?
My understanding is you are trying to branch out the logic of the script based on whether the build command was a success. Here is what you can do:
cat create-image.sh
#!/bin/bash
docker build -q -t test-image .
if [ $? -eq 0 ]; then
echo OK, images created
else
echo FAIL, image not created
exit 1
fi
echo "...DOING OTHER THINGS... (like docker-compose up)"
Let me know if this is what you were looking for.
You don't need a script if you just want to build images before starting containers:
docker-compose --build up
If you must use a script, you can certain call the above command and check its exit code. There is no need to call docker build individually for every service in the docker-compose file.
"Debian 9 64x - LXDE"
I try to create an install script in bash. Lets assume i want to install samba. I call from the mainscript the install script for samba \folder\samba.sh. The script samba.sh should get executed in a new terminal window, so i can watch for install errors.
The script should work like follow description:
The script /mainscript.sh provides only user information, interaction, and executes multiple subscripts (/folder/subscripts.sh).
The script /mainscript.sh needs to create a new terminal window, passes the path, and the name of subscript.sh and executes them in the new terminal window.
The script /mainscript.sh must only execute one subscript (/folder/subscript.sh) at the time! If a subscript.sh is running then the mainscript must wait until the new terminal window gets closed.
The subscript.sh executes some code with root privileges.
Questions:
How can I create a new terminal window, pass the subscript, and execute it in the new terminal window?
How can I make sure that the script (mainscript.sh) only runs one subscript (subscript.sh) at the time?
Example:
mainscript.sh
#!/bin/sh
# This is the content of the mainscript.sh
# subscript1 and subscript2 must not be executed at the same time!
# the mainscript needs to wait when a subscript gets executed!
echo "hello, this script runs in terminal window (((A)))"
xterm /opt/subscript1.sh
echo "samba - Installed"
xterm /opt/subscript2.sh
echo "samba - removed"
subscript1.sh
#!bin/sh
# This is the content of the subscript1
echo "This script runs in a new terminal window (((B)))"
apt-get install samba
# instructions done .... close the terminal window (((B))) now
subscript2.sh
#!bin/sh
# This is the content of the subscript2
echo "This script runs in a new terminal window (((C)))"
apt-get remove samba
# instructions done .... close the terminal window (((C))) now
After clarification that you actually want a new terminal window to appear in LXDE here is a possible solution.
Debian LXDE is likely to have xterm or lxterminal installed. The example below is using lxterminal. For xterm use "xterm -e command"
Start by executing manscript.sh in its own window:
$ lxterminal --command=/mainscript.sh
#!/usr/bin/sh
<section that provides user information>
# Call subscripts that will run in sequence
lxterminal --command=/folder/subscripts.sh
When subscripts.sh finishes, the new terminal window will close and return control to mainscript.sh
You get only one subscript to run at a time by calling these in sequence.
How to find out if script launched using terminal console or without, in gui by .desktop file for example?
I have look over env output and some variables looks promising to check, like test $TERM var. But I want known for sure and a compatible/portable way to do it.
This is needed for script what will have two behaviors for user input, fallback to terminal read or gui input.
The answer by #LeonidMew is incomplete and somewhat incorrect.
You should not detect GUI by presence of STDIN (that's what [ -t 0 ] test does). There are cases when none of STDIN and GUI are available, e.g. when you run the script over ssh session in non-interactive mode. This happens often for CI deploys.
Correct answer heavily depends on your task, in general there are 4 distinct environments:
App is run non-interactively, e.g. from ssh command, spawned as child process without STDIO attached, etc. GUI is missing, STDIN is missing.
App is run interactively from X-session with .desktop file or alike. GUI is present, STDIN is missing.
App is run interactively from linux terminal (ssh, bare text console, hosting recovery console, etc.). GUI is missing, STDIN is present. App can interact with user in text mode via STDIN.
App is run interactively from GUI terminal app, like xterm. GUI is present, STDIN is present.
There are 2 basic tests that can help to identify the environment:
GUI test - whether app can interact with user using graphical windows: test for $DISPLAY env variable.
STDIN test - whether app can interact with user using text console: test for file descriptor 0 (aka STDIN) with if [ -t 0 ]; ...
Combining these two test will give you the environment:
test 1 false + test 2 false: case 1 -- no user interaction available
test 1 true + test 2 false: case 2 -- interact via XWindows
test 1 false + test 2 true: case 3 -- interact via STDIN/console
test 1 true + test 2 true: case 4 -- XWindows or STDIN/console, whichever is preferred
if [ -t 0 ]; then echo "in a terminal"; fi
That tests file descriptor 0, which is stdin. If you're launching your script as a GUI, that test should be false.
Author: glenn jackman
This won't work if the script is run from a terminal, but with input
redirected. – Gordon Davisson
so for the purpose of this discussion, terminal emulator is being
conflated with linux console, and both are being distinguished from a
"gui method" which I'd thought xterm to be, as it opens in a gui... -
JosephHarriott
Purpose of this question was writing script interface usable for text or gui if script run by .desktop shortcut or other gui method.
Or:
$ [ -t 0 ] && echo "in a terminal" || echo "something else"
in a terminal
I'm writing a script that checks something about a Docker container; which container it is depends on user input. So I have code like this:
(define pipes (process (string-append "docker inspect " name)))
To get the result of calling docker inspect $name in the shell. How can I protect this from code injection? Someone could enter someName ; sudo rm -rf / --no-preserve-root and the result wouldn't be nice. I could make it so that it has the effect of docker inspect "$name" or even put it between single quotes but in both cases, someone could enter someName" or someName' instead and the problem is back.
Use the process* function, which takes separate arguments for the command name and its arguments, bypassing the shell to run the program.
(process* "docker" "inspect" name)