Skip to content

Commit d5859c8

Browse files
authored
Provide the devops-toolkit execution script (#209)
1 parent fec9b9c commit d5859c8

File tree

2 files changed

+277
-2
lines changed

2 files changed

+277
-2
lines changed

README.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,42 @@ Below is the versioning strategy for the repository and DockerHub:
4242

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

45-
## Quick start 🔥
45+
## Use devops-toolkit with execution script
46+
47+
The `devops-toolkit` script in this repo helps you use the devops-toolkit in the fast and efficience way.
48+
49+
### Install
50+
51+
```bash
52+
curl -o devops-toolkit https://raw.githubusercontent.com/tungbq/devops-toolkit/main/devops-toolkit
53+
chmod +x devops-toolkit
54+
sudo mv devops-toolkit /usr/local/bin/
55+
```
56+
57+
### Run
58+
59+
Navigate to your working directory then run the devops-toolkit
60+
61+
```bash
62+
# See available commands or get help
63+
devops-toolkit help
64+
# Start a new container
65+
devops-toolkit run
66+
# Start a new container and run a command
67+
devops-toolkit run ls -la
68+
# Execute the shell
69+
devops-toolkit shell
70+
# Update the devops-toolkit
71+
devops-toolkit update
72+
# Remove container
73+
devops-toolkit cleanup
74+
```
75+
76+
## Use devops-toolkit with docker command
77+
78+
In this option you use your own docker command to start and run the devops-toolkit.
79+
80+
### Quick start 🔥
4681

4782
- Use latest tag
4883

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

64-
## Demo 📺
99+
### Demo 📺
65100

66101
```bash
67102
docker run --network host --rm -v ~/.dtc:/dtc tungbq/devops-toolkit:latest samples/run_sample.sh

devops-toolkit

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
#!/bin/bash
2+
3+
# Color codes
4+
RED='\033[0;31m'
5+
GREEN='\033[0;32m'
6+
YELLOW='\033[0;33m'
7+
BLUE='\033[0;34m'
8+
NC='\033[0m' # No Color
9+
10+
# Logging function
11+
log() {
12+
local color=$1
13+
local message=$2
14+
echo -e "${color}${message}${NC}"
15+
}
16+
17+
# Default configuration options
18+
DOCKER_IMAGE="${DOCKER_IMAGE:-tungbq/devops-toolkit:latest}"
19+
CONFIG_MOUNT_PATH="${CONFIG_MOUNT_PATH:-$HOME/.dtc}"
20+
CONTAINER_NAME="${CONTAINER_NAME:-devops_toolkit}"
21+
CONTAINER_SHELL="${CONTAINER_SHELL:-/bin/bash}"
22+
RUN_MODE="${RUN_MODE:-run}"
23+
NETWORK="${NETWORK:---net=host}"
24+
25+
if [ -z "$CONTAINER_NAME" ]; then
26+
log $RED "No CONTAINER_NAME provided"
27+
exit 1
28+
fi
29+
30+
# Function to check if local image is up-to-date with DockerHub
31+
is_image_up_to_date() {
32+
local image="$1"
33+
local repo="${image%:*}"
34+
local tag="${image#*:}"
35+
36+
local local_digest=$(docker image inspect --format='{{index .RepoDigests 0}}' "$image" 2>/dev/null | cut -d'@' -f2)
37+
local remote_digest=$(docker pull -q "$image" > /dev/null 2>&1 && docker image inspect --format='{{index .RepoDigests 0}}' "$image" | cut -d'@' -f2)
38+
39+
[ "$local_digest" = "$remote_digest" ]
40+
}
41+
42+
pull_image() {
43+
local image="$1"
44+
45+
if [[ "$image" != "sha256:"* ]]; then
46+
if docker image inspect "$image" >/dev/null 2>&1; then
47+
if is_image_up_to_date "$image"; then
48+
log $YELLOW "Image $image is up-to-date. Skipping pull."
49+
else
50+
log $BLUE "Local image $image is outdated. Pulling latest version..."
51+
docker pull "$image" || { log $RED "Failed to pull image $image"; exit 1; }
52+
fi
53+
else
54+
log $BLUE "Pulling image $image..."
55+
docker pull "$image" || { log $RED "Failed to pull image $image"; exit 1; }
56+
fi
57+
fi
58+
}
59+
60+
start_container() {
61+
local image="$1"
62+
if ! docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
63+
log $BLUE "Starting new container with image $image..."
64+
docker run -d --name "$CONTAINER_NAME" \
65+
--volume "$PWD:$PWD" \
66+
--volume "$CONFIG_MOUNT_PATH:/dtc" \
67+
--volume "$HOME/.ssh:/root/.ssh" \
68+
--workdir "$PWD" \
69+
--init \
70+
--entrypoint tail \
71+
$NETWORK \
72+
$DOCKER_ARGS \
73+
"$image" -f /dev/null > /dev/null || { log $RED "Failed to start container"; exit 1; }
74+
log $GREEN "Container started successfully"
75+
else
76+
log $YELLOW "Container $CONTAINER_NAME already exists"
77+
fi
78+
}
79+
80+
exec_in_container() {
81+
local command="$1"
82+
83+
local RUN_CMD=$CONTAINER_SHELL
84+
85+
if [ -n "$command" ]; then
86+
RUN_CMD+=" -c $command"
87+
fi
88+
89+
log $BLUE "Executing command in container $CONTAINER_NAME..."
90+
docker exec -it "$CONTAINER_NAME" $RUN_CMD || {
91+
log $RED "Failed to execute command in container $CONTAINER_NAME"; exit 1;
92+
}
93+
}
94+
95+
cleanup() {
96+
log $BLUE "Cleaning up..."
97+
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
98+
docker stop "$CONTAINER_NAME" > /dev/null
99+
docker rm "$CONTAINER_NAME" > /dev/null
100+
log $GREEN "Container $CONTAINER_NAME has been removed."
101+
else
102+
log $YELLOW "Container $CONTAINER_NAME does not exist."
103+
fi
104+
}
105+
106+
update() {
107+
local version="$1"
108+
local new_image
109+
110+
if [ -z "$version" ]; then
111+
new_image="${DOCKER_IMAGE%:*}:latest"
112+
log $BLUE "Updating to the latest version..."
113+
else
114+
new_image="${DOCKER_IMAGE%:*}:$version"
115+
log $BLUE "Updating to version $version..."
116+
fi
117+
118+
if [ "$new_image" == "$DOCKER_IMAGE" ]; then
119+
if is_image_up_to_date "$new_image"; then
120+
log $YELLOW "The specified image ($new_image) is already in use and up-to-date. No update needed."
121+
return
122+
else
123+
log $BLUE "The specified image ($new_image) is in use but outdated. Updating..."
124+
fi
125+
fi
126+
127+
pull_image "$new_image"
128+
cleanup
129+
DOCKER_IMAGE="$new_image"
130+
start_container "$DOCKER_IMAGE"
131+
log $GREEN "Update completed successfully. New image: $DOCKER_IMAGE"
132+
}
133+
134+
version() {
135+
log $BLUE "DevOps Toolkit Version Information:"
136+
log $GREEN "Current Docker Image: $DOCKER_IMAGE"
137+
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
138+
local container_image=$(docker inspect --format='{{.Config.Image}}' "$CONTAINER_NAME")
139+
log $GREEN "Running Container Image: $container_image"
140+
else
141+
log $YELLOW "No running container found."
142+
fi
143+
}
144+
145+
list_versions() {
146+
log $BLUE "Available versions of DevOps Toolkit:"
147+
local repo="${DOCKER_IMAGE%:*}"
148+
curl -s "https://registry.hub.docker.com/v2/repositories/${repo}/tags?page_size=100" | \
149+
jq -r '.results[].name' | sort -V
150+
}
151+
152+
health_check() {
153+
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
154+
local status=$(docker inspect --format='{{.State.Status}}' "$CONTAINER_NAME")
155+
local health=$(docker inspect --format='{{.State.Health.Status}}' "$CONTAINER_NAME")
156+
log $GREEN "Container Status: $status"
157+
log $GREEN "Container Health: ${health:-N/A}"
158+
else
159+
log $RED "Container $CONTAINER_NAME does not exist."
160+
fi
161+
}
162+
163+
show_logs() {
164+
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
165+
docker logs "$CONTAINER_NAME"
166+
else
167+
log $RED "Container $CONTAINER_NAME does not exist."
168+
fi
169+
}
170+
171+
shell_access() {
172+
if docker inspect --type=container "$CONTAINER_NAME" > /dev/null 2>&1; then
173+
log $BLUE "Accessing shell in container $CONTAINER_NAME..."
174+
docker exec -it "$CONTAINER_NAME" $CONTAINER_SHELL
175+
else
176+
log $RED "Container $CONTAINER_NAME does not exist."
177+
fi
178+
}
179+
180+
usage() {
181+
log $BLUE "Usage: $0 [command] [options]"
182+
echo "Commands:"
183+
echo " run [command]: Start a new container and run a command"
184+
echo " exec [command]: Execute a command in an existing container"
185+
echo " cleanup: Remove the container"
186+
echo " update [version]: Update the container image. If version is omitted, updates to latest."
187+
echo " version: Display version information"
188+
echo " list-versions: List available versions of the DevOps toolkit"
189+
echo " health: Perform a health check on the running container"
190+
echo " logs: View the logs of the running container"
191+
echo " shell: Get a shell inside the running container"
192+
}
193+
194+
case "$1" in
195+
run)
196+
RUN_MODE="run"
197+
shift
198+
log $BLUE "Running in 'run' mode..."
199+
pull_image "$DOCKER_IMAGE"
200+
start_container "$DOCKER_IMAGE"
201+
exec_in_container "$@"
202+
;;
203+
exec)
204+
RUN_MODE="exec"
205+
shift
206+
log $BLUE "Running in 'exec' mode..."
207+
exec_in_container "$@"
208+
;;
209+
cleanup)
210+
cleanup
211+
;;
212+
update)
213+
shift
214+
update "$1"
215+
;;
216+
version)
217+
version
218+
;;
219+
list-versions)
220+
list_versions
221+
;;
222+
health)
223+
health_check
224+
;;
225+
logs)
226+
show_logs
227+
;;
228+
shell)
229+
shell_access
230+
;;
231+
help)
232+
usage
233+
exit 0
234+
;;
235+
*)
236+
log $RED "Invalid command: $1"
237+
usage
238+
exit 1
239+
;;
240+
esac

0 commit comments

Comments
 (0)