pax_global_header00006660000000000000000000000064127214342420014513gustar00rootroot0000000000000052 comment=0cfea78ee599e6ffa8646e1e46d4aad8284ee864 docker-clean-2.0.4/000077500000000000000000000000001272143424200140455ustar00rootroot00000000000000docker-clean-2.0.4/.editorconfig000066400000000000000000000002741272143424200165250ustar00rootroot00000000000000root = true [*] indent_style = space indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false docker-clean-2.0.4/.github/000077500000000000000000000000001272143424200154055ustar00rootroot00000000000000docker-clean-2.0.4/.github/ISSUE_TEMPLATE000066400000000000000000000007461272143424200175220ustar00rootroot00000000000000*If you are filing a bug report, please answer these questions. If your issue is not a bug report, you do not need to use this template.* #### 1. What version of Docker-Clean are you running (` docker-clean --version`)? #### 2. What command are you trying to run? #### 3. What did you expect to see? #### 4. What did you see instead ( 'docker-clean -l or --verbose' for the entire log )? #### 5. What are your system specs? Docker Version: Docker-Machine Version: OS/Version: docker-clean-2.0.4/.github/PULL_REQUEST_TEMPLATE000066400000000000000000000003021272143424200206020ustar00rootroot00000000000000- What I did - How I did it - Does it need a test written for it? - Description for the changelog - Does it pass a ShellCheck? (excluding changes to .bats files see our CONTRIBUTING.md) docker-clean-2.0.4/.gitignore000066400000000000000000000000121272143424200160260ustar00rootroot00000000000000.DS_Store docker-clean-2.0.4/.imdone/000077500000000000000000000000001272143424200153765ustar00rootroot00000000000000docker-clean-2.0.4/.imdone/config.json000066400000000000000000000012341272143424200175360ustar00rootroot00000000000000{ "exclude": [ "^(node_modules|bower_components|\\.imdone|target|build|dist|logs)[\\/\\\\]?|\\.(git|svn|hg|npmignore)|\\~$|\\.(jpg|png|gif|swp|ttf|otf)$" ], "watcher": true, "keepEmptyPriority": false, "code": { "include_lists": [ "TODO", "DOING", "DONE", "PLANNING", "FIXME", "ARCHIVE", "HACK", "CHANGED", "XXX", "IDEA", "NOTE", "REVIEW" ] }, "lists": [ { "name": "TODO", "hidden": false } ], "marked": { "gfm": true, "tables": true, "breaks": false, "pedantic": false, "smartLists": true, "langPrefix": "language-" } }docker-clean-2.0.4/.travis.yml000066400000000000000000000030051272143424200161540ustar00rootroot00000000000000language: bash sudo: required services: docker env: global: - DOCKER_VERSION=1.11.0-0~trusty - DOCKER_COMPOSE_VERSION=1.7.0 addons: apt: sources: - debian-sid # Grab shellcheck from the Debian repo (o_O) packages: - shellcheck before_install: - apt-cache madison docker-engine - sudo apt-get -o Dpkg::Options::="--force-confnew" install -y docker-engine=${DOCKER_VERSION} - sudo rm /usr/local/bin/docker-compose - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin - sudo add-apt-repository ppa:duggan/bats --yes - sudo apt-get update -qq - sudo apt-get install -qq bats script: - shellcheck docker-clean - bats tests/docker-clean.bats notifications: slack: secure: MYDLBgnN/PBccyQy93CnEJMLjMa7F+AsIzzfzwPPl8DPj4K2dXoc7zlmaBxbg4KNRunJWND6I4JuN9D+zqUwRrcIuIVx38qv2CHr6PDmF7oS6w2oFw7FnA35jPVshMAqZz2nXc1eFyrnsZ71YV/9XNXr4M5gJn7d8OTHtknqfBm4V8bUQX7Zldo9tK7OziPZ+dyV3TlUqEyZe3YHf4xoSPT00B75JT/zIo+REJr5Wvw4JYScMgbR54WRveGNqSOZbcK8VRAB/NN3Kt0kPuCWjtZbBgNzkIVxoydbN6rrKUh5k+o/4WdfiBkflbrjEfXuAzG3jj1g29xr32WZQlLxUW8uJXPUwTdAnyJ563176bG2pLQxUXLsjanC8Zh9LdREwhg7KYOOE0Gd91PjP2xRJc6RtI+tAV/MURRLxaMbSbzDBAalVVbB4jdQRuEjPp439hfqsqN6P47xnKrq3sV9thjc95PcO6aS2sYTXTo5Qeeh2inz+9GWnzZCU59lD+elVqncuQ44k6j7vsjhv6SnmCHZZgb7PC3CVIrZqwcuGw8eVIJqZ5+nIz3h3qRAnGuGkM+WWiI/avi87BdK8IAPKMG4KJFNw6EWsqXFUIGe4RfqW0nEXAyowePeSDC3ewNFMN2uBVhmKjDI7ynEmpti0yeW5hso58p+lRkasqx86/0= docker-clean-2.0.4/CONTRIBUTING.md000066400000000000000000000023301272143424200162740ustar00rootroot00000000000000# Contributing to Docker-Clean ## Team members * [Killian Brackey](https://github.com/killianbrackey) killian@zzrot.com T: [@kmbrackey](https://twitter.com/kmbrackey) * [Sean Kilgarriff](https://github.com/Skilgarriff) sean@zzrot.com T: [@seankilgarriff](https://twitter.com/SeanKilgarriff) Don't hesitate to get in contact with either one of us with problems, questions, etc. ## Adding new features * Fork it! * Create your feature branch: git checkout -b my-new-feature * Commit your changes: git commit -am 'Add some feature' * Push to the branch: git push origin my-new-feature * Submit a pull request :D ## ShellCheck We use ShellCheck to keep our code consistent and readable. Any feature pushed that does not pass a ShellCheck will fail on Travis build, and thus we cannot accept the pull request. Please lint your code before submitting it! :). (Keep in mind that bats does not have to be ShellChecked, and thus if you are adding tests to .bats don't worry about linting.) You can either download the ShellCheck program: https://github.com/koalaman/shellcheck or use the ShellCheck website: http://www.shellcheck.net/ Don’t get discouraged! We estimate that the response time from the maintainers is around: 24 hours. docker-clean-2.0.4/LICENSE000066400000000000000000000020411272143424200150470ustar00rootroot00000000000000Copyright (c) <2016> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. docker-clean-2.0.4/README.md000066400000000000000000000106731272143424200153330ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/ZZROTDesign/docker-clean.svg?branch=v2.0.4)](https://travis-ci.org/ZZROTDesign/docker-clean)[![GitHub release](https://img.shields.io/github/release/zzrotDesign/docker-clean.svg)](https://github.com/ZZROTDesign/docker-clean/releases) # Docker-Clean [![Join the chat at https://gitter.im/ZZROTDesign/docker-clean](https://badges.gitter.im/ZZROTDesign/docker-clean.svg)](https://gitter.im/ZZROTDesign/docker-clean?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) A simple Shell script to clean up the Docker Daemon. ## Requirements In order to use the volume capabilities, it is required that the Docker Daemon is at least version 1.9+ ## Install curl -s https://raw.githubusercontent.com/ZZROTDesign/docker-clean/v2.0.4/docker-clean | sudo tee /usr/local/bin/docker-clean > /dev/null && \ sudo chmod +x /usr/local/bin/docker-clean ## Homebrew Install brew update brew install docker-clean **UPDATE:** Docker-clean v2.0.3+ will be available without using our tap. However we will keep both maintained. #### Upgrade (for new versions) brew update && brew upgrade docker-clean For curl installs, re-running the script above will install the newest version. ## Usage For a more in depth look at the usage and commands run without browsing the script itself check out our [USAGE.md](https://github.com/ZZROTDesign/docker-clean/blob/master/USAGE.md). docker-clean [optional flags below] Default without arguments deletes stopped containers, dangling volumes, and untagged images. stop Stops and removes all containers, cleans dangling volumes, and networks images Removes all tagged and untagged images, stopped containers, dangling volumes, and networks run Removes all stopped containers, untagged images, dangling volumes, and networks all Stops and removes all containers, images, volumes and networks "Additional Flag options:" -n or --dry-run Adding this additional flag will list items to be removed without executing any stopping or removing commands" -s or --stop Stops all running containers -c or --containers Removes all stopped containers -i or --images Removes all untagged images -net or --networks Removes all empty Networks (all network cleans are only empty) -r or --restart Restarts the docker machine/daemon -d or --created By default, CREATED containers are set to be removed. Adding this flag will ensure that all created containers are not cleaned -t or --tagged Removes all tagged images -a or --all Stops and removes all Containers, Images, AND Restarts docker -l or --log Adding this as an additional flag will list all image, volume, and container deleting output ## Contributing to Docker-Clean ### Team members * [Sean Kilgarriff](https://github.com/Skilgarriff) sean@zzrot.com T: [@seankilgarriff](https://twitter.com/SeanKilgarriff) * [Killian Brackey](https://github.com/killianbrackey) killian@zzrot.com T: [@kmbrackey](https://twitter.com/kmbrackey) Don't hesitate to get in contact with either one of us with problems, questions, etc. Check out our [blog post](https://blog.zzrot.com/docker-clean-utility/) on why we put this script together. ### Adding new features * Fork it! * Create your feature branch: git checkout -b my-new-feature * Commit your changes: git commit -am 'Add some feature' * Push to the branch: git push origin my-new-feature * Submit a pull request :D For any new features you hope to see, you can also edit the REQUESTS.md file. https://github.com/ZZROTDesign/docker-clean/blob/master/REQUESTS.md Don’t get discouraged! We estimate that the response time from the maintainers is around: 24 hours. ### ShellCheck We use ShellCheck to keep our code consistent and readable. Any feature pushed that does not pass a ShellCheck will fail on Travis build, and thus we cannot accept the pull request. Please lint your code before submitting it! :). (Keep in mind that bats does not have to be ShellChecked, and thus if you are adding tests to .bats don't worry about linting.) You can either download the ShellCheck program: https://github.com/koalaman/shellcheck or use the ShellCheck website: http://www.shellcheck.net/ ## License The code is available under the [MIT License](/LICENSE). docker-clean-2.0.4/REQUESTS.md000066400000000000000000000014211272143424200156400ustar00rootroot00000000000000# Requests for new Features Edit this document for any suggestions on features you would like added. Feel free to open an issue as well, but this helps us consolidate new features and details. It also can act as a TODO list. #### The basic template (loose): Detail Explanations: detail Please fill out as much information as you find applicable, this may include commands you would like to be implemented. ## Examples **Completed** New Feature: dry run Explanations: run through commands to see what will be cleaned before removing anything. Desired Flags: -n, --dry-run `docker-clean --dry-run` **Completed** New Feature: clean networking Explanation: networks should also have the option to be cleaned. Desired Flags: -net, --networks `docker-clean -net` ## New Features Below docker-clean-2.0.4/USAGE.md000066400000000000000000000212621272143424200152360ustar00rootroot00000000000000# Usage for Docker Clean v2.0.0 This guide walks through proper usage and briefly explains the command(s) behind the usage for those that are familiar with some of the commands Docker provides. The commands listed run after sanity checks to confirm the command will run properly. docker-clean [optional flags below] Default without arguments deletes stopped containers, dangling volumes, and untagged images. "Additional Flag options:" -n or --dry-run Adding this additional flag will list items to be removed without executing any stopping or removing commands" -s or --stop Stops all running containers -c or --containers Removes all stopped containers -i or --images Removes all untagged images -net or --networks Removes all empty Networks (all network cleans are only empty) -r or --restart Restarts the docker machine/daemon -d or --created By default, CREATED containers are set to be removed. Adding this flag will ensure that all created containers are not cleaned -t or --tagged Removes all tagged images -a or --all Stops and removes all Containers, Images, AND Restarts docker -l or --log Adding this as an additional flag will list all image, volume, and container deleting output ## Dry Run Before going and trying the default usage, if you have sensitive material you wouldn't like cleared and would like to see the results of a run, here is how to run all of the commands with a dry run. Usage for dry-run options: `docker-clean [flags below, excluding -l and --log] -n` or `--dry-run` This will print out the result of each command run in a wrapper that doesn't execute the command. With the newest version (2.0.0+) you can use the `-n` or `--dry-run` as any flag in your execution. ## Default Usage After the very quick installation docker-clean will be ready to go out of the box. Assuming the Docker daemon is running, trying `$ docker-clean` Commands run: ``` # Containers docker rmi -f $(docker images -aq --filter "dangling=true") docker volume rm $(docker volume ls -qf dangling=true) docker network rm ``` will complete the default run through. This simple clean function will only clean out images that do not have a tag, dangling volumes, and empty networks. The network command is a bit more involved and not listed above. We run checks to ensure the networks are unused by inspecting the containers themselves. ## Non Flag Options The following options run a series of commands and are built with particular workflow usages in mind. Each option can be individually accessed by the flags to handpick usage or supplement these options. These options are optional the flags can be run independent of these options. #### Examples ```$ docker-clean stop``` This command will stop and remove all containers (including created), clean dangling volumes, and empty networks. ```$ docker-clean images``` This command will remove all tagged and untagged images not being used by running containers. It will also remove dangling volumes and empty networks. ```$ docker-clean run``` For those of you that are familiar with versions of docker-clean before v2.0.0, this has the same functionality as the old default run. This removes all stopped containers, untagged images, dangling volumes, and empty networks. ``$ docker-clean all`` This is similar to the ```-a```, ```-all``` flag option except it will not restart docker as the flags will. It stops and removes all containers, tagged and untagged images, dangling volumes, and networks. At the bottom of this document is an example of the output of a dry run using this option. ## Flags Then come the additional options and flags. At any point running with a flag `-h`, `--help`, or a flag not specified will bring up the flag reference menu. The help menu is available at the top of this document as well for reference. #### Stop Containers `$ docker-clean -s` or `--stop` Command run: ``` docker stop $(docker ps -q) ``` Stops all running containers and will not remove any images or containers, volumes, or networks. #### Clean Containers `$ docker-clean -c` or `--containers` Commands run: ``` docker rmi -f $(docker images -aq --filter "STATUS=exited") ``` This flag only removes stopped containers. #### Clean Images and Containers `$ docker-clean -i` or `--images` Removes all containers and images. #### Clean All and Restart Daemon `$ docker-clean -a` or `--all` Commands run: ``` docker rm -f $(docker ps -a -q) docker rm -f $(docker images -a -q) docker volume rm $(docker volume ls -qf dangling=true) ``` Restart (Mac, Windows) `docker-machine restart` Restart (Linux) `sudo service docker restart` Stops and removes all containers, images, and dangling volumes and restarts the docker daemon (supports OSX, Windows, and Linux). ### Additional Flags For debugging purposes and so you can see the more traditional output from these commands there are a couple of additional flags. #### Version `docker-clean -v` or `--version` Prints the docker clean version #### Log (Verbose) Adding `-l` or `--log` as an additional flag will print out the full output from the docker commands on each of the other options as opposed to the suppressed output with counts. This typically is the ID of the images, containers, and volumes being removed. The id's have been left in for the `-s`, `--stop` function. Examples: ``` $ docker-clean -l` or `--log` $ docker-clean --containers --log $ docker-clean -s -l ``` ## Dry Run Example Below is a dry run example output. Containers: ``` $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8da973093341 training/webapp "python app.py" 3 seconds ago Up 3 seconds 0.0.0.0:32769->5000/tcp web 3424ffbb418d zzrot/alpine-caddy "tini caddy --conf /e" 3 seconds ago Up 3 seconds extra ``` Images: ``` $ docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE zzrot/alpine-caddy latest 5dac1ba1d438 2 days ago 48.16 MB zzrot/alpine-node latest ab87df339f32 3 weeks ago 25.48 MB zzrot/whale-awkward latest 08e0a241de0d 4 weeks ago 516 B training/webapp latest 6fae60ef3446 11 months ago 348.8 MB ``` ``` $ docker-clean all --dry-run Dry run on stoppage of running containers: Running without -n or --dry-run flag will stop the listed containers: Container ID: 8da973093341 IMAGE: "python"/["app.py"] NAME: "/web" Container ID: 3424ffbb418d IMAGE: "tini"/["caddy","--conf","/etc/Caddyfile"] NAME: "/extra" Dry run on removal of stopped containers: Running without -n or --dry-run flag will remove the listed containers: Container ID: 8da973093341 IMAGE: "python"/["app.py"] NAME: "/web" Container ID: 3424ffbb418d IMAGE: "tini"/["caddy","--conf","/etc/Caddyfile"] NAME: "/extra" Dry run on removal of images: Running without -n or --dry-run flag will remove the listed images: REPOSITORY/TAG: ["zzrot/alpine-caddy:latest"] IMAGE ID: 5dac1ba1d438 REPOSITORY/TAG: ["zzrot/alpine-node:latest"] IMAGE ID: ab87df339f32 REPOSITORY/TAG: ["zzrot/whale-awkward:latest"] IMAGE ID: 08e0a241de0d REPOSITORY/TAG: ["training/webapp:latest"] IMAGE ID: 6fae60ef3446 You've cleared approximately MB: 422 of space! Dry run on removal of dangling volumes: Running without -n or --dry-run flag will stop the listed dangling volumes: DRIVER: "local" NAME: 45bc5fb98fc95e67512e75fcc56fd52b0f443c17010850517f97a30340e45249 DRIVER: "local" NAME: 75e24a294862504426e2e4c4aa83bf69c5f8a5ebc9586518e7f1dd26b7202333 Dangling volumes that would be removed from containers to be deleted... VOLUME: [{"Name":"a7a4020d3739b4306e16a6ddd776b852ed08b4d0cdf4387e048ea123b756941f","Source":"/mnt/sda1/var/lib/docker/volumes/a7a4020d3739b4306e16a6ddd776b852ed08b4d0cdf4387e048ea123b756941f/_data","Destination":"/webapp","Driver":"local","Mode":"","RW":true,"Propagation":""}] VOLUME: [{"Name":"71c6e02b11056d2b379063314b0826773167d8cb11058752821aa6375737805b","Source":"/mnt/sda1/var/lib/docker/volumes/71c6e02b11056d2b379063314b0826773167d8cb11058752821aa6375737805b/_data","Destination":"/webapp","Driver":"local","Mode":"","RW":true,"Propagation":""}] Dry run on removal of networks: No empty networks. Running without -n or --dry-run flag won't remove any networks. ``` ## Issues If you find any issues with these commands, it would be great if you opened an issue, or forked and submitted a pull request! docker-clean-2.0.4/docker-clean000077500000000000000000000622101272143424200163230ustar00rootroot00000000000000#!/bin/bash # Maintained by Sean Kilgarriff and Killian Brackey at ZZROT Design # # The MIT License (MIT) # Copyright © 2016 ZZROT LLC # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # #ENVIRONMENT VARIABLES # @info: Docker-clean current version declare VERSION="2.0.4" # @info: Required Docker version for Volume functionality declare REQUIRED_VERSION="1.9.0" # @info: Required version for docker network inspect filters declare NETWORK_REQUIRED_VERSION="1.10.0" # @info: Boolean for determining which network cleaning function to use declare HAS_NETWORK_VERSION=false # @info: Boolean for storing Docker version info declare HAS_VERSION=false # @info: Boolean for verbose mode declare VERBOSE=false # @info: Boolean for dry run to see before removing declare DRY_RUN=false # @info: Boolean to flag if Containers should be stopped. declare STOP_CONTAINERS=false # @info: Boolean to flag if containers should be deleted. declare CLEAN_CONTAINERS=false # @info: Boolean to flag if images should be deleted. declare CLEAN_IMAGES=false # @info: Boolean to flag if volumes should be deleted. declare CLEAN_VOLUMES=false # @info: Boolean to flag if networks should be deleted. declare CLEAN_NETWORKS=false # @info: Boolean to flag if machine/daemon should be reset. declare RESTART=false # @info: Boolean to flag if tagged images are to be deleted. declare DELETE_TAGGED=false # @info: Boolean to flag if Containers with status Created will be deleted or not. declare DELETE_CREATED=true # @info: Global arrays of objects that would be deleted, used for dry run accuracy. declare -a CONTAINERS_TO_DELETE # Currently in use declare -a IMAGES_IN_USE # Currently in use declare -a IMAGES_TO_DELETE # Currently in use declare -a REMAINING_CONTAINERS # Currently in use declare -a EMPTY_NETWORKS # Currently in use #declare -a VOLUMES_TO_DELETE # Not in use # @info: Docker host to use (default to empty or localhost). declare DOCKER_HOST #FUNCTIONS # @info: Overrides the system docker daemon so we can pass in a host # @args: Global Arguments $@ function docker(){ if [ -z "$DOCKER_HOST" ]; then command "docker" "$@" else command "docker" -H "$DOCKER_HOST" "$@" fi } # @info: Parses and validates the CLI arguments # @args: Global Arguments $@ # TODO: handle use case where just -n or just -l flag is given function parseCli(){ if [[ "$#" -eq 0 ]]; then #CLEAN_CONTAINERS=false # changed to false so doesn't exit containers CLEAN_IMAGES=true CLEAN_VOLUMES=true CLEAN_NETWORKS=true dockerClean fi if [[ "$#" -gt 0 ]]; then #If there is only one flag, and it is dry run or log, set defaults key="$1" case $key in -n | --dry-run) CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true ;; -l | --log) CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true ;; esac while [[ "$#" -gt 0 ]]; do key="$1" val="$2" case $key in stop ) STOP_CONTAINERS=true; CLEAN_CONTAINERS=true; CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true ;; images ) DELETE_TAGGED=true; CLEAN_CONTAINERS=true; CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true ;; run ) CLEAN_CONTAINERS=true; CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true ;; all ) STOP_CONTAINERS=true; DELETE_TAGGED=true; CLEAN_CONTAINERS=true; CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true ;; -H | --host) DOCKER_HOST=$val; shift;; -s | --stop) STOP_CONTAINERS=true ;; -n | --dry-run) DRY_RUN=true ;; -l | --log) VERBOSE=true ;; -c | --containers) CLEAN_CONTAINERS=true ;; -i | --images) CLEAN_IMAGES=true ;; -m | --volumes) CLEAN_VOLUMES=true ;; -net | --networks) CLEAN_NETWORKS=true ;; -r | --restart) RESTART=true ;; -d | --created) DELETE_CREATED=false ;; -t | --tagged) DELETE_TAGGED=true ;; -a | --all) STOP_CONTAINERS=true; DELETE_TAGGED=true; CLEAN_CONTAINERS=true; CLEAN_IMAGES=true; CLEAN_VOLUMES=true; CLEAN_NETWORKS=true; RESTART=true ;; -v | --version) version; exit 0 ;; -h | --help | *) usage; exit 0 ;; esac shift done dockerClean fi } # @info: Prints out Docker-clean current version function version { echo $VERSION } # @info: Prints out usage function usage { echo echo " Docker Clean Usage Options: " echo "-------------------------------" echo echo "-h or --help Opens this help menu" echo "-v or --version Prints the current docker-clean version" echo echo " Running without any options will remove dangling volumes and untagged images only." echo " All of the options are option, and while they overlap they can all be run concurrently." echo " NOTE: By default, created containers will always be included, see -d, --created." echo echo "stop Stops and removes all containers, cleans dangling volumes, and networks" echo echo "images Removes all tagged and untagged images, stopped containers, " echo " dangling volumes, and networks" echo echo "run Removes all stopped containers, untagged images, dangling volumes, and networks" echo echo "all Stops and removes all containers, images, volumes and networks" echo echo "Additional Flag options:" echo echo "-H or --host Specifies the docker host to run against" echo " Useful for docker swarm maintenance" echo " ie: -H 127.0.0.1:4000" echo echo "-n or --dry-run Adding this additional flag will list items to be" echo " removed without executing any stopping or removing commands" echo echo "-s or --stop Stops all running containers" echo echo "-c or --containers Removes all stopped containers" echo echo "-i or --images Removes all untagged images" echo echo "-net or --networks Removes all empty Networks (all network cleans are only empty)" echo echo "-r or --restart Restarts the docker machine/daemon" echo echo "-d or --created By default, CREATED containers are set to be removed. Adding this" echo " flag will ensure that all created containers are not cleaned" echo echo "-t or --tagged Removes all tagged images" echo echo "-a or --all Stops and removes all Containers, Images, AND Restarts docker" echo echo "-l or --log Adding this as an additional flag will list all" echo " image, volume, and container deleting output" } # @info: Prints out 3-point version (000.000.000) without decimals for comparison # @args: Docker Version of the client function printVersion { echo "$@" | awk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; } # @info: Checks Docker Version and then configures the HAS_VERSION var. function checkVersion { local Docker_Version Docker_Version="$(docker --version | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')" if [ "$(printVersion "$Docker_Version")" -gt "$(printVersion "$REQUIRED_VERSION")" ]; then HAS_VERSION=true else echo "Your Version of Docker is below 1.9.0 which is required for full functionality." echo "Please upgrade your Docker daemon. Until then, the Volume and Network processing will not work." fi } # @info: Checks if network inspect filters are compatible function checkNetworkVersion { local Docker_Version Docker_Version="$(docker --version | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')" if [ "$(printVersion "$Docker_Version")" -gt "$(printVersion "$NETWORK_REQUIRED_VERSION")" ]; then echo true fi } # @info: Checks to see if Docker is installed and connected function checkDocker { #Run Docker ps to make sure that docker is installed #As well as that the Daemon is connected. docker ps &>/dev/null DOCKER_CHECK=$? #If Docker Check returns 1 (Error), send a message and exit. if [ ! "$DOCKER_CHECK" ]; then echo "Docker is either not installed, or the Docker Daemon is not currently connected." echo "Please check your installation and try again." exit 1; fi } # @info: Stops all running docker containers. function stop { IFS=$'\n' read -rd '' -a runningContainers <<<"$(docker ps -q)" if $DRY_RUN; then echo "Dry run on stoppage of running containers:" if [[ ! $runningContainers ]]; then echo "No running containers. Running without -n or --dry-run flag won't stop any containers." echo #Spacing else echo "Running without -n or --dry-run flag will stop the listed containers:" echo #Spacing for i in "${runningContainers[@]}"; do local name local path local args name="$(docker inspect -f '{{json .Name}}' "$i")" path="$(docker inspect -f '{{json .Path}}' "$i")" args="$(docker inspect -f '{{json .Args}}' "$i")" echo "Container ID: $i IMAGE: $path/$args NAME: $name" done echo #Spacing fi # End Dry Run else if [ ! "$runningContainers" ]; then echo "No running containers!" else local count=0 echo "Stopping running containers..." for i in "${runningContainers[@]}"; do local output local status local name local path local args name="$(docker inspect -f '{{json .Name}}' "$i")" path="$(docker inspect -f '{{json .Path}}' "$i")" args="$(docker inspect -f '{{json .Args}}' "$i")" docker stop "$i" &>/dev/null status=$? if [[ $status -eq 0 ]] ; then count=$((count+1)) output="STOPPED: ID: $i IMAGE: $path/$args NAME: $name" echo "$output" | log else output="COULD NOT STOP: ID: $i IMAGE: $path/$args NAME: $name" echo "$output" | log fi done echo "Containers stopped: $count" fi fi } # @info: Removes all stopped docker containers. function cleanContainers { if $DRY_RUN; then echo "Dry run on removal of stopped containers:" if [[ ! ${CONTAINERS_TO_DELETE[@]} ]]; then echo "No removable containers. Running without -n or --dry-run flag won't remove any containers." echo #Spacing fi if [[ ${CONTAINERS_TO_DELETE[@]} ]]; then echo "Running without -n or --dry-run flag will remove the listed containers:" echo #Spacing for i in "${CONTAINERS_TO_DELETE[@]}"; do local name local path local args name="$(docker inspect -f '{{json .Name}}' "$i")" path="$(docker inspect -f '{{json .Path}}' "$i")" args="$(docker inspect -f '{{json .Args}}' "$i")" echo "Container ID: $i IMAGE: $path/$args NAME: $name" done echo #Spacing fi # end dry run else if [[ ! "${CONTAINERS_TO_DELETE[@]}" ]]; then echo "No containers To clean!" else local count=0 echo "Cleaning containers..." for i in "${CONTAINERS_TO_DELETE[@]}"; do local output local status local name local path local args name="$(docker inspect -f '{{json .Name}}' "$i")" path="$(docker inspect -f '{{json .Path}}' "$i")" args="$(docker inspect -f '{{json .Args}}' "$i")" docker rm "$i" &>/dev/null status=$? if [[ $status -eq 0 ]] ; then count=$((count+1)) output="DELETED: ID: $i IMAGE: $path/$args NAME: $name" echo "$output" | log else output="COULD NOT DELETE: ID: $i IMAGE: $path/$args NAME: $name" echo "$output" | log fi done echo "Stopped containers cleaned: $count" fi fi } # @info: Removes all untagged/tagged docker images. function cleanImages { if $DRY_RUN; then echo "Dry run on removal of images:" if [[ ! ${IMAGES_TO_DELETE[@]} ]]; then echo "No images. Running without -n or --dry-run flag won't remove any images." echo #Spacing else echo "Running without -n or --dry-run flag will remove the listed images:" echo #Spacing local totalSize=0 for i in "${IMAGES_TO_DELETE[@]}"; do local repotag local size repotag="$(docker inspect -f '{{json .RepoTags}}' "$i")" size="$(docker inspect -f '{{json .Size}}' "$i")" echo "REPOSITORY/TAG: $repotag IMAGE ID: $i" totalSize=$((totalSize+size)) done echoSize $totalSize echo #Spacing fi # End dry run else if [[ ! "${IMAGES_TO_DELETE[@]}" ]]; then echo "No images to delete!" else local count=0 local try=0 echo "Cleaning images..." local -a todelete todelete="${IMAGES_TO_DELETE[*]}" while [[ "$try" -lt "${#IMAGES_TO_DELETE[@]}" ]]; do for i in $(seq 0 "${#IMAGES_TO_DELETE[@]}"); do try=$((try+1)) local output local status local repotag local size local image local validInput validInput=true image="${IMAGES_TO_DELETE[$i]}" image=${image// /} if [[ "${#image}" -lt 12 ]]; then validInput=false fi if [[ $validInput == true ]]; then repotag="$(docker inspect -f '{{json .RepoTags}}' "$image")" size="$(docker inspect -f '{{json .Size}}' "$image")" docker rmi -f "$image" &>/dev/null status=$? if [[ $status -eq 0 ]] ; then count=$((count+1)) totalSize=$((totalSize+size)) output="DELETED: REPOSITORY/TAG: $repotag IMAGE ID: $image" echo "$output" | log #unset "IMAGES_TO_DELETE[$i]" # ERROR value too great for base todelete=("${todelete[@]:0:$i}" "${todelete[@]:(($i+1))}") fi fi done done echo "Images cleaned: $count" echoSize $totalSize fi fi } # @info: Removes all dangling Docker Volumes. function cleanVolumes { IFS=$'\n' read -rd '' -a danglingVolumes <<<"$(docker volume ls -qf dangling=true)" if $DRY_RUN; then echo "Dry run on removal of dangling volumes:" if [[ ! $danglingVolumes ]]; then echo "No existing dangling volumes. Running without -n or --dry-run flag won't remove any dangling volumes." echo else echo "Running without -n or --dry-run flag will stop the listed dangling volumes:" for i in "${danglingVolumes[@]}"; do local driver driver="$(docker volume inspect -f '{{json .Driver}}' "$i")" echo "DRIVER: $driver NAME: $i" echo # for spacing done fi if [[ ${CONTAINERS_TO_DELETE[@]} ]]; then echo "Dangling volumes that would be removed from containers to be deleted..." for j in "${CONTAINERS_TO_DELETE[@]}"; do local status local output local driver name="$(docker inspect -f '{{json .Mounts}}' "$j")" echo VOLUME: "$name" echo # for spacing done echo #For spacing fi # End dry run else if [ ! "$danglingVolumes" ]; then echo "No dangling volumes!" else echo "Cleaning existing dangling volumes..." local count=0 for i in "${danglingVolumes[@]}"; do local status local output local driver driver="$(docker volume inspect -f '{{json .Driver}}' "$i")" docker volume rm "$i" &>/dev/null status=$? if [[ $status -eq 0 ]] ; then count=$((count+1)) output="DELETED DRIVER: $driver NAME: $i" echo "$output" | log else output="COULD NOT DELETE DRIVER: $driver NAME: $i" fi done echo "Volumes cleaned: $count" fi fi } #@ info: Sets global array of empty networks function globalEmptyNetworks { IFS=$'\n' read -rd '' -a networks <<<"$(docker network ls -q)" local -a emptyNetworks for i in "${networks[@]}"; do containers="$(docker network inspect -f '{{json .Containers}}' "$i")" containers=${containers:3} # remove empty container string brackets name="$(docker network inspect -f '{{json .Name}}' "$i")" if [[ "$name" != '"bridge"' ]] && [[ "$name" != '"host"' ]] && [[ "$name" != '"none"' ]]; then emptyNetworks+=("$i") fi done if [[ "${REMAINING_CONTAINERS[@]}" ]]; then for j in "${REMAINING_CONTAINERS[@]}"; do local -a connectedNetworks connectedNetworks="$(docker inspect -f '{{json .NetworkSettings.Networks}}' "$j")" length="${#emptyNetworks[@]}" for k in $(seq 0 "$length"); do checking="${emptyNetworks[$k]}" if [[ $connectedNetworks =~ $checking ]]; then emptyNetworks=("${emptyNetworks[@]:0:$k}" "${emptyNetworks[@]:(($k+1))}") fi done done fi for x in "${emptyNetworks[@]}"; do echo "$x" done } function cleanNetworks { if [[ $HAS_NETWORK_VERSION == true ]]; then if [[ $DRY_RUN == true ]]; then echo "Dry run on removal of networks:" if [[ ! ${EMPTY_NETWORKS[@]} ]]; then echo "No empty networks. Running without -n or --dry-run flag won't remove any networks." else echo "Running without -n or --dry-run flag will remove the listed networks:" for i in "${EMPTY_NETWORKS[@]}"; do local name name="$(docker network inspect -f '{{json .Name}}' "$i")" local driver driver="$(docker network inspect -f '{{json .Driver}}' "$i")" echo "Network ID: $i NAME: $name DRIVER: $driver" done fi # End Dry Run else if [[ "${#EMPTY_NETWORKS[@]}" -eq 0 ]]; then echo "No empty networks!" echo else local count=0 echo "Removing empty networks..." for i in "${EMPTY_NETWORKS[@]}"; do if docker network rm "$i" 2>&1 | log ; then count=$((count+1)) fi done echo "Networks removed: $count" echo fi fi else echo "Docker-clean only has support for Network removal on Docker Versions 1.10 and up." echo "Docker will not enable you to remove networks in use, and you can use the " echo "following command at your own risk: docker network rm \$(docker network ls -q)" fi } # @info: Restarts and reRuns docker-machine env active machine function restartMachine { operating_system=$(testOS) #if [[ $DRY_RUN == false ]]; then if [[ $operating_system =~ mac || $operating_system =~ windows ]]; then active="$(docker-machine active)" if [[ $DRY_RUN == false ]]; then docker-machine restart "$active" else echo "Dry run on Daemon restart:" echo "Command that would be used: docker-machine restart $active" fi eval "$(docker-machine env "$active")" echo "Running docker-machine env $active..." echo "New IP Address for" "$active" ":" "$(docker-machine ip)" elif [[ $operating_system =~ linux ]]; then if [[ $DRY_RUN == false ]]; then echo "Restarting Docker..." echo "Restarting this service requires sudo privileges" else echo "Dry run on Daemon restart, requires sudo to check platform:" fi init_system=$(linuxInitSystem) # Upstart covers SysV and OpenRC as well. if [[ $init_system =~ upstart ]]; then if [[ $DRY_RUN == false ]]; then sudo service "docker" restart else echo "Restart command that would be run: sudo service docker restart" fi elif [[ $init_system =~ systemd ]]; then if [[ $DRY_RUN == false ]]; then sudo systemctl restart docker.service else echo "Restart command that would be run: sudo systemctl restart docker.service" fi elif [[ $init_system =~ rc ]]; then if [[ $DRY_RUN == false ]]; then sudo launchctl restart "docker" else echo "Restart command that would be run: sudo launchctl restart docker" fi fi else echo It appears your OS is not compatible with our docker engine restart echo Windows compatibility work in progress echo It you feel you are seeing this as an error please visit echo "https://github.com/ZZROTDesign/docker-clean and open an issue." exit 2 fi } # @info: Runs the checks before the main code can be run. function Check { checkDocker checkVersion } # @info: Accepts input to output if verbose mode is flagged. function log { read -r IN if $VERBOSE; then echo "$IN" fi } ## ** Script for testing os ** # Modified for our usage from: # Credit https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux/17072017#17072017?newreg=b1cdf253d60546f0acfb73e0351ea8be # Echo mac for Mac OS X, echo linux for GNU/Linux, echo windows for Window function testOS { if [ "$(uname)" == "Darwin" ]; then # Do something under Mac OS X platform echo mac elif [ "$(uname -s)" == "Linux" ]; then # Do something under GNU/Linux platform echo linux #!/bin/bash elif [ "$(uname -s)" == "MINGW32_NT" ]; then # Do something under Windows NT platform echo windows fi } #END FUNCTIONS # Function for testing linux initSystem function linuxInitSystem { # To include hidden files shopt -s nullglob dotglob # Get sudo privileges if [ $EUID != 0 ]; then sudo "$?" &>/dev/null #sudo "$0" "$@" &>/dev/null #Recommended, but doesn't pass shell check fi # Directories to check # Upstart covers SysV and OpenRC as well. upstart=(/etc/init.d/docker) systemd=(/etc/systemd/docker) rc=(/etc/rc.d/docker) initSystem="" #files=(/some/dir/*) if [ ${#upstart[@]} -gt 0 ]; then initSystem=upstart elif [ ${#systemd[@]} -gt 0 ]; then initSystem=systemd elif [ ${#rc[@]} -gt 0 ]; then initSystem=rc fi echo $initSystem } # @info: Echos the size of images removed in various measurements # @args: The number of bytes moved function echoSize { local mega local giga if [[ $1 -gt 0 ]]; then mega=$(($1 / 1000000)) giga=$(($1 / 1000000000)) if [[ $giga == 0 ]]; then echo "You've cleared approximately MB: $mega of space!" else echo "You've cleared approximately MB: $mega or GB: $giga of space!" fi fi } # @info: Returns 0 if array contains string, 1 if it does not. # @info: NOTE: Must run status check after calling to check result. # @args: Arg 1 is string, arg2 is array function arrayContains { local seeking=$1; shift local in=1 for element; do if [[ "$element" == "$seeking" ]]; then in=0 break fi done echo $in #for i in "${@:2}"; do # [[ "$i" == "$1" ]] && return 0; #done #return 1 } # @info: sets global container variable arrays # @args: delete --> returns containers to be deleted, remaining --> returns non-deleted containers function containersToDelete { local -a remainingContainers if $STOP_CONTAINERS && $DELETE_CREATED; then IFS=$'\n' read -rd '' -a containers <<<"$(docker ps -aq)" elif $STOP_CONTAINERS && ! $DELETE_CREATED; then IFS=$'\n' read -rd '' -a containers <<<"$(docker ps -q -f STATUS=exited -f STATUS=running)" IFS=$'\n' read -rd '' -a remainingContainers <<<"$(docker ps -q -f STATUS=created)" elif ! $STOP_CONTAINERS && $DELETE_CREATED; then IFS=$'\n' read -rd '' -a containers <<<"$(docker ps -q -f STATUS=exited -f STATUS=created)" IFS=$'\n' read -rd '' -a remainingContainers <<<"$(docker ps -q -f STATUS=running)" fi if [[ $1 =~ delete ]]; then for value in "${containers[@]}" ; do echo "$value" done elif [[ $1 =~ remaining ]]; then for value in "${remainingContainers[@]}" ; do echo "$value" done fi } #@ info sets global images to delete for dry run. CURRENTLY NOT IN USE function usedImages { # For loop goes through appending to array of images with images used in containers queued to remove #declare -a used for i in "${REMAINING_CONTAINERS[@]}" ; do # IF not used by other containers new="$(docker inspect -f '{{json .Image}}' "$i")" new=${new##*:} # Cuts inspect output off before the colon -- "sha:" new=${new:0:12} # Take only first 12 characters from image sha echo "$new" done } function globalImagesToDelete { # starts with all images and then pulls just the unused images #if $DELETE_TAGGED; then if $DELETE_TAGGED; then IFS=$'\n' read -rd '' -a images <<<"$(docker images -a -q)" else IFS=$'\n' read -rd '' -a images <<<"$(docker images -aq --filter "dangling=true")" fi #else # IFS=$'\n' read -rd '' -a images <<<"$(docker images -aq --filter "dangling=true")" #fi for i in "${images[@]}" ; do # Call arry contains function if [[ $(arrayContains "$i" "${IMAGES_IN_USE[@]}") -eq 1 ]]; then echo "$i" fi done } # @info: sets global variables for a dry run function setGlobal { IFS=$'\n' CONTAINERS_TO_DELETE=($(containersToDelete delete)) REMAINING_CONTAINERS=($(containersToDelete remaining)) # Add time delta IMAGES_IN_USE=($(usedImages)) IMAGES_TO_DELETE=($(globalImagesToDelete)) EMPTY_NETWORKS=($(globalEmptyNetworks)) HAS_NETWORK_VERSION=($(checkNetworkVersion)) #VOLUMES_TO_DELETE=($(volumesToDelete)) } # @info: Default run option, cleans stopped containers and images function dockerClean { #if [[ $DRY_RUN == true ]]; then setGlobal #fi if $STOP_CONTAINERS; then stop fi if $CLEAN_CONTAINERS; then cleanContainers fi if $CLEAN_IMAGES; then cleanImages fi if $CLEAN_VOLUMES && $HAS_VERSION; then cleanVolumes fi if $CLEAN_NETWORKS && $HAS_VERSION; then cleanNetworks fi if $RESTART; then restartMachine fi } # @info: Main function Check parseCli "$@" # Used for testing global arrays : <<'END' echo EMTPY NETWORKS for i in "${EMPTY_NETWORKS[@]}"; do echo "$i" done echo USED IMAGES for i in "${IMAGES_IN_USE[@]}"; do echo "$i" done echo echo UNUSED IMAGES for j in "${IMAGES_TO_DELETE[@]}"; do echo "$j" done END exit 0 docker-clean-2.0.4/tests/000077500000000000000000000000001272143424200152075ustar00rootroot00000000000000docker-clean-2.0.4/tests/docker-clean.bats000077500000000000000000000162061272143424200204210ustar00rootroot00000000000000#!/usr/bin/env bats # PRODUCTION Bats Tests for Travis CI # Initial pass at testing for docker-clean # These tests simply test each of the options currently available # To run the tests locally run brew install bats or # sudo apt-get install bats and then bats batsTest.bats # WARNING: Runing these tests will clear all of your images/Containers @test "Check that docker client is available" { command -v docker #[ $status = 0 ] } @test "Run docker ps (check daemon connectivity)" { run docker ps [ $status = 0 ] } @test "Docker Clean Version echoes" { run ./docker-clean -v [ $status = 0 ] } @test "Default build and clean testing helper functions" { build [ $status = 0 ] clean runningContainers="$(docker ps -aq)" [ ! $runningContainers ] } @test "Help menu opens" { # On -h flag run ./docker-clean -h [[ ${lines[0]} =~ "Options:" ]] run ./docker-clean --help [[ ${lines[0]} =~ "Options:" ]] # On unspecified tag run ./docker-clean -z [[ ${lines[0]} =~ "Options:" ]] #clean } # Runs most powerful command and confirms nothing cleaned @test "Test Dry Run (runs most powerful removal command in dry run)" { buildWithVolumes [ $status = 0 ] runningContainers="$(docker ps -aq)" stoppedContainers="$(docker ps -qf STATUS=exited )" untaggedImages="$(docker images -aq --filter "dangling=true")" listedImages="$(docker images -aq)" volumes="$(docker volume ls -q)" # Run command with most power run ./docker-clean all --dry-run [ $status = 0 ] afterRunningContainers="$(docker ps -aq)" afterStoppedContainers="$(docker ps -qf STATUS=exited )" afterUntaggedImages="$(docker images -aq --filter "dangling=true")" afterListedImages="$(docker images -aq)" afterVolumes="$(docker volume ls -q)" [[ $runningContainers == $afterRunningContainers ]] [[ $stoppedContainers == $afterStoppedContainers ]] [[ $untaggedImages == $afterUntaggedImages ]] [[ $listedImages == $afterListedImages ]] [[ $volumes == $afterVolumes ]] clean } @test "Test network removal" { build [ $status = 0 ] run docker network create one run docker network create two run docker network connect testNet container run ./docker-clean --networks used="$(docker network ls -qf name='one')" empty="$(docker network ls -qf name='two')" [[ $used ]] [[ -z $empty ]] } @test "Test container stopping (-s --stop)" { build [ $status = 0 ] runningContainers="$(docker ps -q)" [ $runningContainers ] run ./docker-clean -s runningContainers="$(docker ps -q)" [ ! $runningContainers ] clean } @test "Clean Containers test" { stoppedContainers="$(docker ps -a)" untaggedImages="$(docker images -aq --filter "dangling=true")" run docker kill $(docker ps -a -q) [ "$stoppedContainers" ] run ./docker-clean stoppedContainers="$(docker ps -qf STATUS=exited )" createdContainers="$(docker ps -qf STATUS=created)" [ ! "$stoppedContainers" ] [ ! "$createdContainers" ] clean } @test "Clean All Containers Test" { build [ $status = 0 ] allContainers="$(docker ps -a -q)" [ "$allContainers" ] run ./docker-clean -s -c allContainers="$(docker ps -a -q)" [ ! "$allContainers" ] clean } # TODO: create an untagged image test case @test "Clean images (not all)" { skip build [ $status = 0 ] untaggedImages="$(docker images -aq --filter "dangling=true")" [ "$untaggedImages" ] run ./docker-clean untaggedImages="$(docker images -aq --filter "dangling=true")" [ ! "$untaggedImages" ] clean } @test "Clean all function for images" { build [ $status = 0 ] listedImages="$(docker images -aq)" [ "$listedImages" ] run ./docker-clean -a listedImages="$(docker images -aq)" [ ! "$listedImages" ] clean } @test "Clean Volumes function" { buildWithVolumes [ $status = 0 ] run docker stop extra volumes="$(docker volume ls -q)" [ "$volumes" ] run docker rm -f extra clean } # TODO test case for the -qf STATUS exited # TODO Write test with an untagged image @test "Default run through -- docker-clean (without arguments)" { build [ $status = 0 ] stoppedContainers="$(docker ps -a)" untaggedImages="$(docker images -aq --filter "dangling=true")" run docker kill $(docker ps -a -q) [ "$stoppedContainers" ] #[ "$untaggedImages" ] run ./docker-clean #stoppedContainers="$(docker ps -qf STATUS=exited )" #createdContainers="$(docker ps -qf STATUS=created)" danglingVolumes="$(docker volume ls -qf dangling=true)" [ ! "$danglingVolumes" ] [ "$stoppedContainers" ] #[ ! "$createdContainers" ] #[ ! "$untaggedImages" ] clean } # Test for counting correctly @test "Testing counting function" { build [ $status = 0 ] run docker kill $(docker ps -a -q) run ./docker-clean -s -c [[ $output =~ "Cleaning containers" ]] [[ $output =~ "1" ]] build run docker run -d -P --name web -v /webapp training/webapp python app.py run ./docker-clean -s -c [[ $output =~ "Cleaning containers" ]] [[ $output =~ "2" ]] #run ./docker-clean -i #[[ $output =~ "Cleaning images..." ]] #[[ $output =~ "4" ]] clean } # Tests logging outputs properly @test "Verbose log function (-l --log)" { build [ $status = 0 ] docker stop "$(docker ps -q)" stoppedContainers="$(docker ps -a -q)" run ./docker-clean -c -l 2>&1 [[ $output =~ "$stoppedContainers" ]] clean } # Testing for successful restart @test "Restart function" { operating_system=$(testOS) if [[ $operating_system =~ "mac" || $operating_system =~ 'windows' ]]; then ./docker-clean -a | grep 'started' run docker ps &>/dev/null [ $status = 0 ] elif [[ $operating_system =~ "linux" ]]; then ./docker-clean -a | grep 'stop' #ps -e | grep 'docker' run docker ps &>/dev/null [ $status = 0 ] else echo "Operating system not valid" [[ false ]] fi } # Helper FUNCTIONS function build() { if [ $(docker ps -a -q) ]; then docker rm -f $(docker ps -a -q) fi run docker pull zzrot/whale-awkward run docker pull zzrot/alpine-ghost run docker pull zzrot/alpine-node run docker run -d --name container zzrot/alpine-caddy } function buildWithVolumes { if [ $(docker ps -a -q) ]; then docker rm -f $(docker ps -a -q) fi run docker pull zzrot/whale-awkward run docker pull zzrot/alpine-ghost run docker run -d -P --name extra -v /webapp zzrot/alpine-caddy } function clean() { run docker kill $(docker ps -a -q) run docker rm -f $(docker ps -a -q) run docker rmi -f $(docker images -aq) } ## ** Script for testing os ** # Credit https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux/17072017#17072017?newreg=b1cdf253d60546f0acfb73e0351ea8be # Echo mac for Mac OS X, echo linux for GNU/Linux, echo windows for Window function testOS { if [ "$(uname)" == "Darwin" ]; then # Do something under Mac OS X platform echo mac elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then # Do something under GNU/Linux platform echo linux elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then # Do something under Windows NT platform echo windows fi } docker-clean-2.0.4/tests/playground.sh000077500000000000000000000105571272143424200177420ustar00rootroot00000000000000#!/bin/bash # This script is used to build and try test cases during development # OPTIONS="Hello Quit" # select opt in $OPTIONS; do # if [ "$opt" = "Quit" ]; then # echo done # exit # elif [ "$opt" = "Hello" ]; then # echo Hello World # else # clear # echo bad option # fi # done ## ** Script for testing os ** # Credit https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux/17072017#17072017?newreg=b1cdf253d60546f0acfb73e0351ea8be function testOS { if [ "$(uname)" == "Darwin" ]; then # Do something under Mac OS X platform echo MacOsX elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then # Do something under GNU/Linux platform echo Linux elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then # Do something under Windows NT platform echo Windows fi } testOS function counter { runningContainers="$(docker ps -a -q)" #"$(docker images -aq)" #"$(docker ps -qf STATUS=exited )" #"$(docker ps -q)" length=${#runningContainers[@]} number_of_occurrences=$(grep -o "" <<< "$runningContainers" | wc -l) echo $runningContainers echo $number_of_occurrences declare -p $runningContainers 2> /dev/null | grep -q '^declare \-a' && echo array || echo array not found } function networks { echo NETWORKS IFS=$'\n' read -rd '' -a networks <<<"$(docker network ls -q)" declare -a emptyNetworks : <<'END' for i in "${networks[@]}"; do containers="$(docker network inspect -f '{{json .Containers}}' "$i")" containers=${containers:3} if [[ -z $containers ]]; then echo EMTPY fi echo Container: ${containers} name="$(docker network inspect -f '{{json .Name}}' "$i")" if [[ -n "$containers" ]] && [[ "$name" != '"bridge"' ]] && [[ "$name" != '"host"' ]] && [[ "$name" != '"none"' ]]; then echo "$i" emptyNetworks+=("$i") fi done END } #networks #echo $running_Count function countTest { echo got here toCount="$1" echo arg passed: $toCount size=$((${#toCount} % 12 )) size=$size echo $size number=$toCount | grep -o " " | wc -l #number_of_occurrences=$(grep -o "" <<< "$toCount" | wc -l) echo $number_of_occurrences } #unningContainers="$(docker ps -a -q)" #number=$(count "$runningContainers") #echo $number #count function count { toCount="$1" length=${#toCount} ## Works on OSX, not Linux #number_of_occurrences=$(grep -o "" <<< "$toCount" | wc -l) if [[ $length != 0 ]]; then number_of_occurrences=$(($length % 12 + 1)) fi echo $number_of_occurrences } function cleanContainers { stoppedContainers="$(docker ps -qf STATUS=exited )" createdContainers="$(docker ps -qf STATUS=created)" stopped_count=$(count stoppedContainers) created_count=$(count createdContainers) if [ ! "$stoppedContainers" ]; then echo No Containers To Clean! else echo Cleaning containers... docker rm $stoppedContainers &>/dev/null echo Stopped containers cleaned: $stopped_count fi if [ "$createdContainers" ]; then docker rm $createdContainers &>/dev/null echo Created containers cleaned: $created_count fi } function arrayContains { for i in "${@:2}"; do [[ "$i" == "$1" ]] && return 0; done return 1 } function build() { if [ "$(docker ps -a -q)" ]; then docker rm -f $(docker ps -a -q) fi docker pull zzrot/whale-awkward docker pull zzrot/alpine-caddy docker pull zzrot/alpine-node docker run -d -P --name extra -v /webapp zzrot/alpine-caddy docker run -d -P --name web -v /webapp training/webapp python app.py docker network create testNet docker network create testNet2 docker network connect testNet web docker network connect testNet2 extra #run docker run -d ghost #run docker run -d alpine-caddy #run docker kill ghost } containsElement () { local e for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done return 1 } array=("something to search for" "a string" "test2000") arrayContains "a string" "${array[@]}" #echo $? build #images=$(docker images -a -q) #echo ${#images} #../docker-clean --images #after=$(docker images -a -q) #echo ${#after} #count "$(docker images -a -q)" #count "$(docker ps -a -q)" # Verbosity testing