Skip to content

Commit

Permalink
Provide the devops-toolkit execution script (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
tungbq authored Aug 31, 2024
1 parent fec9b9c commit d5859c8
Show file tree
Hide file tree
Showing 2 changed files with 277 additions and 2 deletions.
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,42 @@ Below is the versioning strategy for the repository and DockerHub:

_NOTE_: In the following section, we use the latest tag in the documentation, but you can specify your desired tag based on your needs.

## Quick start 🔥
## Use devops-toolkit with execution script

The `devops-toolkit` script in this repo helps you use the devops-toolkit in the fast and efficience way.

### Install

```bash
curl -o devops-toolkit https://raw.githubusercontent.com/tungbq/devops-toolkit/main/devops-toolkit
chmod +x devops-toolkit
sudo mv devops-toolkit /usr/local/bin/
```

### Run

Navigate to your working directory then run the devops-toolkit

```bash
# See available commands or get help
devops-toolkit help
# Start a new container
devops-toolkit run
# Start a new container and run a command
devops-toolkit run ls -la
# Execute the shell
devops-toolkit shell
# Update the devops-toolkit
devops-toolkit update
# Remove container
devops-toolkit cleanup
```

## Use devops-toolkit with docker command

In this option you use your own docker command to start and run the devops-toolkit.

### Quick start 🔥

- Use latest tag

Expand All @@ -61,7 +96,7 @@ _NOTE_: In the following section, we use the latest tag in the documentation, bu
- You can replace `~/.dtc` with any desired folder path on your VM.
- Remove the `-v ~/.dtc:/dtc` option if you do not wish to store configurations on the host (not recommended for configuration reuse).

## Demo 📺
### Demo 📺

```bash
docker run --network host --rm -v ~/.dtc:/dtc tungbq/devops-toolkit:latest samples/run_sample.sh
Expand Down
240 changes: 240 additions & 0 deletions devops-toolkit
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
#!/bin/bash

# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Logging function
log() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}

# Default configuration options
DOCKER_IMAGE="${DOCKER_IMAGE:-tungbq/devops-toolkit:latest}"
CONFIG_MOUNT_PATH="${CONFIG_MOUNT_PATH:-$HOME/.dtc}"
CONTAINER_NAME="${CONTAINER_NAME:-devops_toolkit}"
CONTAINER_SHELL="${CONTAINER_SHELL:-/bin/bash}"
RUN_MODE="${RUN_MODE:-run}"
NETWORK="${NETWORK:---net=host}"

if [ -z "$CONTAINER_NAME" ]; then
log $RED "No CONTAINER_NAME provided"
exit 1
fi

# Function to check if local image is up-to-date with DockerHub
is_image_up_to_date() {
local image="$1"
local repo="${image%:*}"
local tag="${image#*:}"

local local_digest=$(docker image inspect --format='{{index .RepoDigests 0}}' "$image" 2>/dev/null | cut -d'@' -f2)
local remote_digest=$(docker pull -q "$image" > /dev/null 2>&1 && docker image inspect --format='{{index .RepoDigests 0}}' "$image" | cut -d'@' -f2)

[ "$local_digest" = "$remote_digest" ]
}

pull_image() {
local image="$1"

if [[ "$image" != "sha256:"* ]]; then
if docker image inspect "$image" >/dev/null 2>&1; then
if is_image_up_to_date "$image"; then
log $YELLOW "Image $image is up-to-date. Skipping pull."
else
log $BLUE "Local image $image is outdated. Pulling latest version..."
docker pull "$image" || { log $RED "Failed to pull image $image"; exit 1; }
fi
else
log $BLUE "Pulling image $image..."
docker pull "$image" || { log $RED "Failed to pull image $image"; exit 1; }
fi
fi
}

start_container() {
local image="$1"
if ! docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
log $BLUE "Starting new container with image $image..."
docker run -d --name "$CONTAINER_NAME" \
--volume "$PWD:$PWD" \
--volume "$CONFIG_MOUNT_PATH:/dtc" \
--volume "$HOME/.ssh:/root/.ssh" \
--workdir "$PWD" \
--init \
--entrypoint tail \
$NETWORK \
$DOCKER_ARGS \
"$image" -f /dev/null > /dev/null || { log $RED "Failed to start container"; exit 1; }
log $GREEN "Container started successfully"
else
log $YELLOW "Container $CONTAINER_NAME already exists"
fi
}

exec_in_container() {
local command="$1"

local RUN_CMD=$CONTAINER_SHELL

if [ -n "$command" ]; then
RUN_CMD+=" -c $command"
fi

log $BLUE "Executing command in container $CONTAINER_NAME..."
docker exec -it "$CONTAINER_NAME" $RUN_CMD || {
log $RED "Failed to execute command in container $CONTAINER_NAME"; exit 1;
}
}

cleanup() {
log $BLUE "Cleaning up..."
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
docker stop "$CONTAINER_NAME" > /dev/null
docker rm "$CONTAINER_NAME" > /dev/null
log $GREEN "Container $CONTAINER_NAME has been removed."
else
log $YELLOW "Container $CONTAINER_NAME does not exist."
fi
}

update() {
local version="$1"
local new_image

if [ -z "$version" ]; then
new_image="${DOCKER_IMAGE%:*}:latest"
log $BLUE "Updating to the latest version..."
else
new_image="${DOCKER_IMAGE%:*}:$version"
log $BLUE "Updating to version $version..."
fi

if [ "$new_image" == "$DOCKER_IMAGE" ]; then
if is_image_up_to_date "$new_image"; then
log $YELLOW "The specified image ($new_image) is already in use and up-to-date. No update needed."
return
else
log $BLUE "The specified image ($new_image) is in use but outdated. Updating..."
fi
fi

pull_image "$new_image"
cleanup
DOCKER_IMAGE="$new_image"
start_container "$DOCKER_IMAGE"
log $GREEN "Update completed successfully. New image: $DOCKER_IMAGE"
}

version() {
log $BLUE "DevOps Toolkit Version Information:"
log $GREEN "Current Docker Image: $DOCKER_IMAGE"
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
local container_image=$(docker inspect --format='{{.Config.Image}}' "$CONTAINER_NAME")
log $GREEN "Running Container Image: $container_image"
else
log $YELLOW "No running container found."
fi
}

list_versions() {
log $BLUE "Available versions of DevOps Toolkit:"
local repo="${DOCKER_IMAGE%:*}"
curl -s "https://registry.hub.docker.com/v2/repositories/${repo}/tags?page_size=100" | \
jq -r '.results[].name' | sort -V
}

health_check() {
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
local status=$(docker inspect --format='{{.State.Status}}' "$CONTAINER_NAME")
local health=$(docker inspect --format='{{.State.Health.Status}}' "$CONTAINER_NAME")
log $GREEN "Container Status: $status"
log $GREEN "Container Health: ${health:-N/A}"
else
log $RED "Container $CONTAINER_NAME does not exist."
fi
}

show_logs() {
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
docker logs "$CONTAINER_NAME"
else
log $RED "Container $CONTAINER_NAME does not exist."
fi
}

shell_access() {
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
log $BLUE "Accessing shell in container $CONTAINER_NAME..."
docker exec -it "$CONTAINER_NAME" $CONTAINER_SHELL
else
log $RED "Container $CONTAINER_NAME does not exist."
fi
}

usage() {
log $BLUE "Usage: $0 [command] [options]"
echo "Commands:"
echo " run [command]: Start a new container and run a command"
echo " exec [command]: Execute a command in an existing container"
echo " cleanup: Remove the container"
echo " update [version]: Update the container image. If version is omitted, updates to latest."
echo " version: Display version information"
echo " list-versions: List available versions of the DevOps toolkit"
echo " health: Perform a health check on the running container"
echo " logs: View the logs of the running container"
echo " shell: Get a shell inside the running container"
}

case "$1" in
run)
RUN_MODE="run"
shift
log $BLUE "Running in 'run' mode..."
pull_image "$DOCKER_IMAGE"
start_container "$DOCKER_IMAGE"
exec_in_container "$@"
;;
exec)
RUN_MODE="exec"
shift
log $BLUE "Running in 'exec' mode..."
exec_in_container "$@"
;;
cleanup)
cleanup
;;
update)
shift
update "$1"
;;
version)
version
;;
list-versions)
list_versions
;;
health)
health_check
;;
logs)
show_logs
;;
shell)
shell_access
;;
help)
usage
exit 0
;;
*)
log $RED "Invalid command: $1"
usage
exit 1
;;
esac

0 comments on commit d5859c8

Please sign in to comment.