In my Dockerfile I'm trying to download the latest WordPress version without any content inside it, but I'm having trouble automating the latest version number so that I don't have to manually change it when the new version of WordPress comes out.
In my Dockerfile I have
ARG LATESTWPVER="$(curl -s https://api.wordpress.org/core/version-check/1.5/ | head -n 4 | tail -n 1)"
ADD $(https://downloads.wordpress.org/release/wordpress-$LATESTWPVER-no-content.zip) /var/www/latest.zip
But the problem is that my LATESTWPVER is not 4.9.8, and I get the error
ADD failed: stat /var/lib/docker/tmp/docker-builder962069305/$(https:/downloads.wordpress.org/release/wordpress-$(curl -s https:/api.wordpress.org/core/version-check/1.5/ | head -n 4 | tail -n 1)-no-content.zip): no such file or directory
It passes the entire command and I'd like to have the output of that command.
In my shell file the
#!/bin/bash
WP_LATEST="$(curl -s https://api.wordpress.org/core/version-check/1.5/ | head -n 4 | tail -n 1)"
echo $WP_LATEST
will return the number 4.9.8.
From the error, I'm guessing that you can only assign something to the variable, but not execute it. Is there a way to execute a command and assign it to a variable and pass it as an argument?
A Dockerfile is not a shell or a build script, so it will not execute what you pass in ARG. There is a workaround - define the version as an ARG and pass that during build.
Dockerfile:
--
FROM ubuntu:latest
ARG LATESTWPVER
RUN echo $LATESTWPVER
ADD https://downloads.wordpress.org/release/wordpress-$LATESTWPVER-no-content.zip /var/www/latest.zip
docker build --build-arg LATESTWPVER=`curl -s https://api.wordpress.org/core/version-check/1.5/ | head -n 4 | tail -n 1` .
Sending build context to Docker daemon 6.656kB
Step 1/4 : FROM ubuntu:latest
---> 113a43faa138
Step 2/4 : ARG LATESTWPVER
---> Using cache
---> 64f47dcfe7fa
Step 3/4 : RUN echo $LATESTWPVER
---> Running in eb5fdd005d77
4.9.8
Removing intermediate container eb5fdd005d77
---> 1015629b927e
Step 4/4 : ADD https://downloads.wordpress.org/release/wordpress-$LATESTWPVER-no-content.zip /var/www/latest.zip
Downloading [==================================================>] 7.118MB/7.118MB
---> 72f0d3790e51
Successfully built 72f0d3790e51
Related
We have a main Linux server, say M, where we have files like below (for 2 months, and new files arriving daily)
Folder1
PROCESS1_20211117.txt.gz
PROCESS1_20211118.txt.gz
..
..
PROCESS1_20220114.txt.gz
PROCESS1_20220115.txt.gz
We want to copy only the latest file on our processing server, say P.
So as of now, we were using the below command, on our processing server.
rsync --ignore-existing -azvh -rpgoDe ssh user#M:${TargetServerPath}/${PROCSS_NAME}_*txt.gz ${SourceServerPath}
This process worked fine until now, but from now, in the processing server, we can keep files only up to 3 days. However, in our main server, we can keep files for 2 months.
So when we remove older files from the processing server, the rsync command copies all files from main server to the processing server.
How can I change rsync command to copy only latest file from Main server?
*Note: the example above is only for one file. We have multiple files on which we have to use the same command. Hence we cannot hardcode any filename.
What I tried:
There are multiple solutions, but all seems to be when I want to copy latest file from the server I am running rsync on, not on the remote server.
Also I tried running below to get the latest file from main server, but I cannot pass variable to SSH in my company, as it is not allowed. So below command works if I pass individual path/file name, but cannot work as with variables.
ssh M 'ls -1 ${TargetServerPath}/${PROCSS_NAME}_*txt.gz|tail -1'
Would really appreciate any suggestions on how to implement this solution.
OS: Linux 3.10.0-1160.31.1.el7.x86_64
ssh quoting is confusing - to properly quote it, you have to double-quote it locally.
Handy printf %q trick is helpful - quote the relevant parts.
file=$(
ssh M "ls -1 $(printf "%q" "${getServerPath}/${PROCSS_NAME}")_*.txt.gz" |
tail -1
)
rsync --ignore-existing -azvh -rpgoDe ssh user#M:"$file" "${SourceServerPath}"
or maybe nicer to run tail -n1 on the remote, so that minimum amount of data are transferred (we only need one filename, not them all), invoke explicit shell and pass the variables as shell arguments:
file=$(ssh M "$(printf "%q " bash -c \
'ls -1 "$1"_*.txt.gz | tail -n1'
'_' "${TargetServerPath}/${PROCSS_NAME}"
)")
Overall, I recommend doing a function and using declare -f :
sshqfunc() { echo "bash -c $(printf "%q" "$(declare -f "$1"); $1 \"\$#\"")"; };
work() {
ls -1 "$1"_*txt.gz | tail -1
}
tmp=$(ssh M "$(sshqfunc work)" _ "${TargetServerPath}/${PROCSS_NAME}")
or you can also use the mighty declare to transfer variables to remote - then run your command inside single quotes:
ssh M "
$(declare -p TargetServerPath PROCSS_NAME);
"'
ls -1 ${TargetServerPath}/${PROCSS_NAME}_*txt.gz | tail -1
'
I am using oh-my-zsh and I have been trying to develop a custom completion script for sdkman.
However I have encountered a small problem when trying to mutualize some of the commands.
Below is the beginning of the completion script. There are three functions using the _describe method to output a completion help.
#compdef sdk
zstyle ':completion:*:descriptions' format '%B%d%b'
# Gets candidate lists and removes all unecessery things just to get candidate names
__get_candidate_list() {
echo `sdk list | grep --color=never "$ sdk install" | sed 's/\$ sdk install //g' | sed -e 's/[\t ]//g;/^$/d'`
}
__get_current_installed_list() {
echo `sdk current | sed "s/Using://g" | sed "s/\:.*//g" | sed -e "s/[\t ]//g;/^$/d"`
}
__describe_commands() {
local -a commands
commands=(
'install: install a program'
'uninstall: uninstal an existing program'
)
_describe -t commands "Commands" commands && ret=0
}
__describe_install() {
local -a candidate_list
candidate_list=( $( __get_candidate_list ) )
_describe -t candidate_list "Candidates available" candidate_list && ret=0
}
__describe_uninstall() { # FIXME THis is not working, it only displays candidate list
local -a candidates_to_uninstall
candidates_to_uninstall=( $( __get_current_installed_list ) )
_describe -t candidates_to_uninstall "Uninstallable candidates" candidates_to_uninstall && ret=0
}
The __get_candidate_list echoes the following values:
ant asciidoctorj bpipe ceylon crash cuba cxf gaiden glide gradle grails groovy groovyserv infrastructor java jbake kotlin kscript lazybones leiningen maven micronaut sbt scala spark springboot sshoogr vertx visualvm
The __get_current_installed_list echoes the following values:
gradle java kotlin maven sbt scala
The second part of the script below is where we call everything so that the completion script is used correctly by zsh:
function _sdk() {
local ret=1
local target=$words[2]
_arguments -C \
'1: :->first_arg' \
'2: :->second_arg' \
&& ret=0
case $state in
first_arg)
__describe_commands
;;
second_arg)
case $target in
install)
__describe_install
;;
uninstall)
__describe_uninstall
;;
*)
;;
esac
;;
esac
return $ret
}
_sdk "$#"
The problem is the following: when I type sdk install I get the right output, the one from the __get_candidate_list method BUT when I use sdk uninstall it still gives me the output from __get_candidate_list althought I am expecting __get_current_installed_list output.
EDIT: After a bit of debugging, it seems that zsh is not at fault here. I can't figure out why, but sdkman gives me the same output with both sdk list and sdk current (After the sed commands) from inside the completion script. IN my shell, both commands work properly with shell.
Is there something wrong with the way I use the _describe method ?
Is there anything else I am not seeing ?
Thanks for your help.
So I finally found a workaround to fix this but it is not ideal.
I chose to launch the commands in the background when launching the plugin, and fill text files with the results, so that completion scripts can use these after.
Below is the code I used in the zsh-sdkman.plugin.zsh file, in case my github repository disappears:
# --------------------------
# -------- Executed on shell launch for completion help
# --------------------------
# NOTE: Sdkman seems to always output the candidate list rather than the currently installted list when we do this through the completion script
# There are two goals in the code below:
# - Optimization: the _sdkman_get_candidate_list command can take time, so it is done once and in background
# - Bug correction: correct the problem with sdkman command output explained above
# WARNING: We are setting this as a local variable because we don't have it yet at the time of initialization
# A better approach would be welcome
SDKMAN_DIR_LOCAL=~/.sdkman
# Custom variables for later
export ZSH_SDKMAN_CANDIDATE_LIST_HOME=~/.zsh-sdkman.candidate-list
export ZSH_SDKMAN_INSTALLED_LIST_HOME=~/.zsh-sdkman.current-installed-list
_sdkman_get_candidate_list() {
(sdk list | grep --color=never "$ sdk install" | sed 's/\$ sdk install //g' | sed -e 's/[\t ]//g;/^$/d' > $ZSH_SDKMAN_CANDIDATE_LIST_HOME &)
}
_sdkman_get_current_installed_list() {
(sdk current | sed "s/Using://g" | sed "s/\:.*//g" | sed -e "s/[\t ]//g;/^$/d" > $ZSH_SDKMAN_INSTALLED_LIST_HOME &)
}
# "sdk" command is not found if we don't do this
source "$SDKMAN_DIR_LOCAL/bin/sdkman-init.sh"
# Initialize files with available candidate list and currently installted candidates
_sdkman_get_candidate_list "$#"
_sdkman_get_current_installed_list "$#"
For more information, you can see the complete repository of my plugin: https://github.com/matthieusb/zsh-sdkman
If you have another cleaner solution, I'll be willing to make the necessary modifications, or don't hesitate to make a pull request on the project.
Getting below error during platform installation:
"Required libaio package is not found. ..."
However, above package is already installed:
rpm -q libaio
libaio-0.3.107-10.el6.x86_64
Here is output from the installation script:
./platform-setup-x64-linux-4.4.3.10393.sh
Unpacking JRE ...
Preparing JRE ...
Starting Installer ...
May 30, 2018 6:51:23 PM java.util.prefs.FileSystemPreferences$2 run
INFO: Created system preferences directory in java.home.
Verifying if the libaio package is installed. /opt/appdynamics/platform/installer/checkLibaio.sh
I got this too... I was running from command-line as a non-root user:
./platform-setup-x64-linux-4.4.3.10393.sh -q -varfile /appd/home/Install/response.varfile
I added the shell expand(-x) switch and log to the command(s) like so:
bash -x ./platform-setup-x64-linux-4.4.3.10393.sh -q -varfile /appd/home/Install/response.varfile > install.log 2>&1
If we tail the last bit of that log you get, this response in debug mode:
Verifying if the libaio package is installed. /opt/appdynamics/platform/installer/checkLibaio.sh
Required libaio package is not found. For instructions on installing
the missing package, refer to https://docs.appdynamics.com/display/PRO44/Enterprise+Console+Requirements
and the script checkLibaio.sh isn't left there... so you cannot figure it out easily. I also have a RedHat variant with the packages installed:
rpm -qa | grep libaio
libaio-0.3.109-13.el7.x86_64
Strangely enough I have one VM from the same image that will install the distribution just fine, and one that will not, so on the broken install (where I really want to install this). I ran another command from the expanded view of the install.log, which was a really long JVM command line. Anyways I got it to work and then made a looping script to retrieve the file (Because AppD for some reason removes the check script before you can look at it). The script is as follows:
#!/bin/sh
# Script used to check if the machine has libaio on it or not.
cat /dev/null > /opt/appdynamics/platform/installer/.libaio_status
chmod 777 /opt/appdynamics/platform/installer/.libaio_status
# Check if the dpkg or rpm command exists before running it.
command -v dpkg >/dev/null 2>&1
OUT=$?
if [ $OUT -eq 0 ];
then
if [ `dpkg -l | grep -i libaio* | wc -l` -gt 0 ];
then
echo SUCCESS >> /opt/appdynamics/platform/installer/.libaio_status
exit 0
fi
else
command -v rpm >/dev/null 2>&1
OUT=$?
if [ $OUT -eq 0 ];
then
if [ `rpm -qa | grep -i libaio* | wc -l` -gt 0 ];
then
echo SUCCESS >> /opt/appdynamics/platform/installer/.libaio_status
exit 0
fi
fi
fi
echo FAILURE >> /opt/appdynamics/platform/installer/.libaio_status
exit 1
I you run this script like me on the faulty platform what you will discover is that your version of Linux has both:
dpkg
and
rpm
installed. To work around this you should temporarily make a name change to one of these two package manager executables so it cannot be found (by your shell environment).
Most common here will be that you are running a RedHat variant where someone chose to install dpkg (For who knows what reason). If so desired remove that package and the install should be successful.
Script as -
/bin/bash
1 START_TIME=($date +%s)
echo "calling enviroment variable"
and when i tried to run tho above script i got
error as
calling enviroment variable
/bin/bash 22-1-2016 line 1 : command not found
You should start your script with a she-bang (source) therefore :
/bin/bash
should be
#!/bin/bash
I have just began playing around with docker. While trying out method 1 from meteorhacks:meteord, I get the folowing error
=> You don't have an meteor app to run in this image.
Here is what I have done after creating the basic counter demo meteor app.
docker build -t app .
Sending build context to Docker daemon 11.75 MB
Step 0 : FROM meteorhacks/meteord:base
---> 528baf8d4263
Step 1 : MAINTAINER MeteorHacks Pvt Ltd.
---> Running in 6d7e7eb6ebce
---> d69fefdbeb70
Removing intermediate container 6d7e7eb6ebce
Step 2 : ONBUILD copy ./ /app
---> Running in e68618104dfa
---> c253ae966ea1
Removing intermediate container e68618104dfa
Step 3 : ONBUILD run bash $METEORD_DIR/on_build.sh
---> Running in e51e557c2b05
---> a6a6a1be9147
Removing intermediate container e51e557c2b05
Successfully built a6a6a1be9147
then ( I already initiated a mongo container exposing 27017 and grabbed the internal ip address which was 171.17.0.1)
docker run -d \
-e ROOT_URL=http://localhost:3000 \
-e MONGO_URL=mongodb://172.17.0.1:27017/ \
-e MONGO_OPLOG_URL=mongodb://172.17.0.1:27017/ \
-p 8080:80 \
app
I get the error when I do this and then run docker logs <container id>
Can someone guide me on this?
Thanks in advance.
This error comes from scripts/run_app.sh, which is the ENTRYPOINT of the base Dockerfile.
It checks for the presence of:
/bundle folder, or
/built_app, or
$BUNDLE_URL
If your counter demo Dockerfile didn't populate /bundle or /built_app folders, then you need to make sure you are defining ENV BUNDLE_URL with the right url.