Filtering system to allow multiple containers.
This commit is contained in:
parent
8a72ec4469
commit
ed7dc83f95
2 changed files with 144 additions and 45 deletions
|
@ -16,7 +16,10 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
property RunningContainer.found
|
||||
property RunningContainer.found false
|
||||
property RunningContainer.count 0
|
||||
|
||||
property RunningContainer.lines
|
||||
property RunningContainer.id
|
||||
property RunningContainer.image
|
||||
property RunningContainer.created
|
||||
|
@ -24,51 +27,36 @@ property RunningContainer.status
|
|||
property RunningContainer.ports
|
||||
property RunningContainer.name
|
||||
|
||||
# Constructor to fetch a running container.
|
||||
# First argument is what to fetch, and second is matching attribute.
|
||||
# Example of first arguments: "named" to find by name, "created" to find by creation date,
|
||||
# "withid" to find by container id, "withimage" to find by image, "withstatus" to check status, "withport" to find all having this port forwarded....
|
||||
# Constructor to fetch one or many running container.
|
||||
# Arguments are the various filters to find containers. See: RunningContainer.filter for reference.
|
||||
# NOTE: Multiple containers can be matched. If so, all properties contain the value for each container per line.
|
||||
# NOTE: If no container is found, a message will be printed, and the constructor will exit with false.
|
||||
# Signature: (<string matchType>, <string matchValue>)
|
||||
# Signature: ([string[] filters])
|
||||
RunningContainer.constructor() {
|
||||
matchType=$1
|
||||
matchValue=$2
|
||||
lines=""
|
||||
case $matchType in
|
||||
withid)
|
||||
lines="$(RunningContainer.findLineByValue 1 == $matchValue)"
|
||||
;;
|
||||
withimage)
|
||||
lines="$(RunningContainer.findLineByValue 2 == $matchValue)"
|
||||
;;
|
||||
created)
|
||||
lines="$(RunningContainer.findLineByValue 4 == $matchValue)"
|
||||
;;
|
||||
withstatus)
|
||||
lines="$(RunningContainer.findLineByValue 5 == $matchValue)"
|
||||
;;
|
||||
withport)
|
||||
lines="$(RunningContainer.findLineByValue 6 ~ $matchValue)"
|
||||
;;
|
||||
named)
|
||||
lines="$(RunningContainer.findLineByValue 7 == $matchValue)"
|
||||
if [ -z "$lines" ]; then # Sometimes, when no ports are forwarded, the name is in the 6th field.
|
||||
lines="$(RunningContainer.findLineByValue 6 == $matchValue)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ ! -z $lines ]; then
|
||||
this.found = true
|
||||
this.id = "$(echo $lines | awk -F " {2,}" '{ print $1 }')"
|
||||
this.image = "$(echo $lines | awk -F " {2,}" '{ print $2 }')"
|
||||
this.created = "$(echo $lines | awk -F " {2,}" '{ print $4 }')"
|
||||
this.status = "$(echo $lines | awk -F " {2,}" '{ print $5 }')"
|
||||
this.ports = "$(echo $lines | awk -F " {2,}" '{ print $6 }')"
|
||||
this.name = "$(echo $lines | awk -F " {2,}" '{ print $7 }')"
|
||||
else
|
||||
this.found = false
|
||||
fi
|
||||
args=( "$@" )
|
||||
this.lines = "$($(Docker.Utils.DockerCommand) ps --all | awk -F " {2,}" 'NR>1 { print $1,";",$2,";",$3,";",$4,";",$5,";",$6,($7 != "" ? (";"$7) : "") }')"
|
||||
# Apply filters
|
||||
for ((i=0; i < ${#args[@]}; i++)); do
|
||||
filterName=${args[$i]}
|
||||
|
||||
case $filterName in
|
||||
with_id | with_image | created | with_status | with_port | named)
|
||||
# The next argument is the value of the filter, so we skip it.
|
||||
i=$(expr "$i" + 1)
|
||||
filterValue=${args[$i]}
|
||||
this._baseFilter $filterName $filterValue
|
||||
;;
|
||||
running | exited | stopped)
|
||||
this._baseFilter $filterName
|
||||
;;
|
||||
*)
|
||||
echo "Unknown filter $filterName." 1>&2;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
this._updateProperties
|
||||
# Print error message in STDERR when no containers are found.
|
||||
if [ "$(this.found)" == false ]; then echo "No container found matching those filters." 1>&2; fi
|
||||
}
|
||||
|
||||
# Finds all containers in "docker ps" with a certain field matching a value and returns their lines.
|
||||
|
@ -77,7 +65,118 @@ RunningContainer.findLineByValue() {
|
|||
fieldId=$1
|
||||
operation=$2
|
||||
fieldValue=$3
|
||||
docker ps | awk -F " {2,}" -v value="$fieldValue" 'NR>1 && $'"$fieldId"' '"$operation"' value'
|
||||
# YES. I know. You shouldn't do that with AWK, but variables, FOR SOME REASON, are not properly passed to AWK.
|
||||
this.lines | awk -F " ; " '$'"$fieldId"' '"$operation"' "'"$fieldValue"'" { print $1,";",$2,";",$3,";",$4,";",$5,";",$6,($7 != "" ? (";"$7) : "") }'
|
||||
}
|
||||
|
||||
# Internal function which filters. See: RunningContainer.filter for reference.
|
||||
# Signature: (<string filterName>, [string filterValue])
|
||||
RunningContainer._baseFilter() {
|
||||
filterName=$1
|
||||
filterValue=$2
|
||||
#echo -n "Applying filter $filterName (previous count $(this.lines | wc -l))..." 1>&2
|
||||
case $filterName in
|
||||
with_id)
|
||||
this.lines = "$(this.findLineByValue 1 == $filterValue)"
|
||||
;;
|
||||
with_image)
|
||||
this.lines = "$(this.findLineByValue 2 == $filterValue)"
|
||||
;;
|
||||
created)
|
||||
this.lines = "$(this.findLineByValue 4 == $filterValue)"
|
||||
;;
|
||||
with_status)
|
||||
this.lines = "$(this.findLineByValue 5 == $filterValue)"
|
||||
;;
|
||||
running)
|
||||
this.lines = "$(RunningContainer.findLineByValue 5 ~ "Up")"
|
||||
;;
|
||||
exited | stopped)
|
||||
this.lines = "$(this.findLineByValue 5 "~" "Exited")"
|
||||
;;
|
||||
with_port)
|
||||
this.lines = "$(this.findLineByValue 6 ~ $filterValue)"
|
||||
;;
|
||||
named)
|
||||
lines="$(this.findLineByValue 7 "~" $filterValue)"
|
||||
if [ -z "$lines" ]; then # Sometimes, when no ports are forwarded, the name is in the 6th field.
|
||||
lines="$(this.findLineByValue 6 "~" $filterValue)"
|
||||
fi
|
||||
this.lines = "$lines"
|
||||
;;
|
||||
esac
|
||||
#echo " New count: $(this.lines | wc -l)." 1>&2
|
||||
}
|
||||
|
||||
# Updates property data from fetched lines.
|
||||
# No argument
|
||||
RunningContainer._updateProperties() {
|
||||
if [ ! -z "$(this.lines)" ]; then
|
||||
this.found = true
|
||||
this.count = $(this.lines | wc -l)
|
||||
this.id = "$(this.lines | awk -F " ; " '{ print $1 }')"
|
||||
this.image = "$(this.lines | awk -F " ; " '{ print $2 }')"
|
||||
this.created = "$(this.lines | awk -F " ; " '{ print $4 }')"
|
||||
this.status = "$(this.lines | awk -F " ; " '{ print $5 }')"
|
||||
this.ports = "$(this.lines | awk -F " ; " '{ if($7 != "") { print $6 } }')" # If field 7 is null, that means field 6 is the name, so there are no ports.
|
||||
this.name = "$(this.lines | awk -F " ; " '{ print ($7 != "") ? $7 : $6 }')"
|
||||
else
|
||||
this.found = false
|
||||
this.count = 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Filters all containers assigned to the instance and removes all instances not corresponding to it.
|
||||
# Filters with a value: with_id, with_image, created, with_status, with_port, named
|
||||
# Filters without value: running, exited
|
||||
# Filter types:
|
||||
# - "named" to find by name
|
||||
# - "created" to find by creation date,
|
||||
# - "with_id" to find by container id
|
||||
# - "with_image" to find by image
|
||||
# - "with_status" to check status
|
||||
# - "with_port" to find all having this port forwarded
|
||||
# - "running" to find all containers running
|
||||
# - "exited" or "stopped" to find all containers stopped.
|
||||
# Signature: (<string filterName>, [string filterValue])
|
||||
RunningContainer.filter() {
|
||||
filterName=$1
|
||||
filterValue=$2
|
||||
this._baseFilter $filterName $filterValue
|
||||
this._updateProperties
|
||||
}
|
||||
|
||||
# Applies a docker command to all containers
|
||||
# Signature: (<string command>, [string[] arguments])
|
||||
RunningContainer.applyToAll() {
|
||||
cmd=$1
|
||||
args=${@:2}
|
||||
for container in $(this.id); do
|
||||
$(Docker.Utils.DockerCommand) $cmd $args $container
|
||||
done
|
||||
}
|
||||
|
||||
# Kills all containers assigned to this instance.
|
||||
# Signature: ([string[] arguments])
|
||||
RunningContainer.kill() {
|
||||
$this.applyToAll kill $@
|
||||
}
|
||||
|
||||
# Removes all containers assigned to this instance.
|
||||
# Signature: ([string[] arguments])
|
||||
RunningContainer.rm() {
|
||||
$this.applyToAll rm $@
|
||||
}
|
||||
|
||||
# Removes all containers assigned to this instance.
|
||||
# Signature: ([string[] arguments])
|
||||
RunningContainer.remove() {
|
||||
$this.applyToAll rm $@
|
||||
}
|
||||
|
||||
# Waits for all containers assigned to this instance to stop and echo their exit code.
|
||||
# Signature: ([string[] arguments])
|
||||
RunningContainer.wait() {
|
||||
$this.applyToAll wait $@
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ba000379d7f736f5ad27a609588e555fe94361d0
|
||||
Subproject commit 8d92cad72064b3c3f038d250ba5c2c1a098bfe43
|
Loading…
Reference in a new issue