I am not exactly sure what is wrong with your build, but your Jenkins Dockerfile looks unnecessarily complicated. Here is a simple Dockerfile that does what you want:
FROM jenkins/jenkins:lts
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
That installs the plugins defined in plugins.txt
.
This should be enough to install your plugins automatically. However if you want to configure a complete Jenkins instance from a configuration file, check out this Jenkins plugin that allows Jenkins to be completely configured from YAML.
From the discussion in the comments it is apparent that your main concern is to create as script with multiple selections, rather than focus on copying/moving files themselves, and the file operations are just an example. This functionality can be achieved via dialog
command, which allows creating text user interfaces, with --checklist
flag specifically; however there's nothing in the standard shell-only toolbox to achieve what you want. Hence, dialog
is an appropriate tool for this job.
Below you will find an example script. While the script implements only 3
options that were discussed, it provides a decent starting point which users can extent further, and also addresses mutually exclusive options as mentioned in the comments. Particularly, the multiple selection is addressed in menu()
function, which serves as a wrapper for dialog
with --checklist
option
To keep things simple, all you really need is this:
output=$(dialog --clear --backtitle "Backtitle. Use <SPACE> to select." --title "My Dialog" \
--checklist "Select all that apply" 50 50 100 \
checksum "SHA-256" off \
copy "Copy only (exclusive with move)" off \
move "Move only (exclusive with copy)" off 2>&1 > /dev/tty)
This saves the selection of multiple items to variable $output
. Note that `2>&1 > /dev/tty) at the end are crucial to saving the return value into variable. But see the script below for more practical example:
#!/bin/bash
puke(){
# function to exit with specific error message
# analogous to 'die' in Perl
printf ">>> Errors were encountered: %s\n" "$1" && exit
} > /dev/stderr
menu(){
# dialog --help documents the option as follows:
# --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...
# tags are what the output returns.
# We can use word-splitting
# and iterate over output of this function in order. Of course first option
# being checksum will always work and is not mutually exclusive with anything else
dialog --clear --backtitle "Backtitle. Use <SPACE> to select." --title "My Dialog" \
--checklist "Select all that apply" 50 50 100 \
checksum "SHA-256" off \
copy "Copy only (exclusive with move)" off \
move "Move only (exclusive with copy)" off || puke
} 2>&1 1>/dev/tty
select_file(){
dialog --backtitle "Choose file by typing or navigating and selecting with <SPACE>" --fselect "/etc/" \
20 50 || puke
} 2>&1 1>/dev/tty
iter_actions(){
# variables are available to child functions
# Since we call iter_actions in main(), this
# function also knows about main's variable $fselect
for i ; do
case "$i" in
checksum) sha256sum "$fselect" ;;
copy) cp "$fselect" /tmp ;;
move) mv "$fselect" /tmp ;;
esac
done
}
main(){
# here I'm using /etc but you can use $PWD to default to user's
# current working directory, or accept positional parameters from command-line
# as in $1, $2 and so forth
fselect=$( select_file "/etc" )
actions=$(menu)
printf "\r%b" "\033c" # this clear the screen
case "$actions" in
*copy*move|*move*copy) puke "Mutually exclusive options selected" ;;
*) iter_actions $actions ;; # note here variable is unquoted on purpose
esac
}
# script entry point
main "$@"
For further research:
Best Answer
This script defines a function
walk()
and then runswalk
on the first argument passed to the script.The function first defines a local variable (one known only to the function and its children)
indent
indent
is locally defined as"${2:-0}"
. This means that if$2
(the second argument received by thewalk
command) is unset, then make it0
. This variable islocal
so that you cannot pass a second argument to the script yourself.The function then prints the contents of the directory specified on the command line (
$1
) in this formatThis means, print
$indent
number of spaces, then print the name of the directory as a string (so a number is not expected), then print a newline.Then the function runs a loop
This assigns every non-hidden file or sub-directory in
$1
(the directory specified as the first argument towalk
) to the variableentry
and loops over them, running this command on them:This means, if
entry
is a directory, then runwalk
onentry
. Nowwalk
has a second argument$((indent+4))
, which will be used instead of0
as the new value ofindent
. The effect of this is that the first level directory is not indented at all, but the second level directories are indented 4 spaces, the third level 8 spaces, etc. Sinceentry
is now the first argument,$1
of thewalk
function, it will recurse throughout the structure.The script ends by running the
walk
function on the positional parameter$1
, the first argument passed to the script. Usage could beThis means
directory
is$1
andwalk
will be run ondirectory
.It would be nice if the script printed regular files I think, but they would look confusing without some elaborate formatting. I recommend using
tree
for this purpose instead of the script!