diff --git a/RunningContainer.shc b/RunningContainer.shc
index 9518f86..9457c7f 100644
--- a/RunningContainer.shc
+++ b/RunningContainer.shc
@@ -16,7 +16,10 @@
# along with this program. If not, see .
#
-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: (, )
+# 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 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 filterValue])
+RunningContainer.filter() {
+ filterName=$1
+ filterValue=$2
+ this._baseFilter $filterName $filterValue
+ this._updateProperties
+}
+
+# Applies a docker command to all containers
+# Signature: (, [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 $@
+}
diff --git a/libraries/oop b/libraries/oop
index ba00037..8d92cad 160000
--- a/libraries/oop
+++ b/libraries/oop
@@ -1 +1 @@
-Subproject commit ba000379d7f736f5ad27a609588e555fe94361d0
+Subproject commit 8d92cad72064b3c3f038d250ba5c2c1a098bfe43