Skip to content

Features/cc1 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@
# commonCore
A collection of Bash scripts/utilities that one can source in their own bash scripts.
# commonCoreSh
A collection of Bash scripts/utilities that one can source in their own bash scripts. This feature set is currently UNSTABLE and is not recommended for use in production.

# HOW TO USE
Use at your own direction, so long it is NOT utilized in closed source applications.

Make sure you download the repository as is, and to not change any files in the resulting directories.
If you want to take advantage of these scripts, source `sourcecore.sh`, or consider sourcing it in your profile via `source sourcecore.sh`

# FEATURES
## comphash
comphash performs an md5sum comparison between two files. It will not perform this operation if it detects either argument as a directory.

## dutil (docker util)
The most useful utility so far. Performs some docker compose based actions, such as bouncing a service, building then bouncing, or allowing for easier container ps searching.
Might be ported over as it's own standalone package. maybe not.

One of the most useful is the shortcut of `dutil shell [container name]`, which does the equivalent of `docker exec -it [container name] /bin/bash`. If the container does not support /bin/bash, it will fallback to using /bin/sh instead.

## initdocker
initdocker creates a couple of Docker files on your behalf, such as a skeleton Compose file, an empty Dockerfile, and some starter Bash scripts.
If you're intimately familiar with Docker, you probably won't need to use the bash scripts and can rely on the functions `dutil` offers.

## logging
Sourcing the library will let you utilize a couple logging notations in your scripts
3 changes: 3 additions & 0 deletions bin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Files under this directory get installed into /usr/local/bin

HIGHLY HIGHLY HIGHLY UNSTABLE FOR NOW
159 changes: 159 additions & 0 deletions bin/dutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package main

import (
"fmt"
"os"
"os/exec"
"strings"
)

func main() {
if len(os.Args) < 2 {
usage()
os.Exit(2)
}

// Check if docker compose is installed
if _, err := exec.Command("docker", "compose", "version").CombinedOutput(); err != nil {
fmt.Println("Docker compose v2 is not installed")
os.Exit(1)
}

command := os.Args[1]
switch command {
case "net", "network", "networks":
runCommand("docker", "network", "ls")

case "ps":
if len(os.Args) < 3 {
runCommand("docker", "ps", "-a")
} else {
containerName := os.Args[2]
runCommand("docker", "ps", "-a", "-f", "name="+containerName)
}

case "psg":
if len(os.Args) < 3 {
runCommand("docker", "ps", "-a")
} else {
searchTerm := os.Args[2]
output, err := exec.Command("docker", "ps", "-a").Output()
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
}

lines := strings.Split(string(output), "\n")
for _, line := range lines {
if strings.Contains(line, searchTerm) {
fmt.Println(line)
}
}
}

case "rebuild":
runCommandSequence(
[]string{"docker", "compose", "down"},
[]string{"docker", "compose", "build", "."},
[]string{"docker", "compose", "up", "-d"},
)

case "reload":
composeFile := ""
if len(os.Args) > 2 {
composeFile = os.Args[2]
runCommandSequence(
[]string{"docker", "compose", "-f", composeFile, "down"},
[]string{"docker", "compose", "-f", composeFile, "up", "-d"},
)
} else {
runCommandSequence(
[]string{"docker", "compose", "down"},
[]string{"docker", "compose", "up", "-d"},
)
}

case "shell":
if len(os.Args) < 3 {
usage()
fmt.Println("Error: Missing container name")
os.Exit(1)
}

containerName := os.Args[2]
// Try bash first
cmd := exec.Command("docker", "exec", containerName, "/bin/bash")
if err := cmd.Run(); err == nil {
fmt.Println("Starting /bin/bash in", containerName)
runInteractiveCommand("docker", "exec", "-it", containerName, "/bin/bash")
} else {
// Try sh as fallback
cmd = exec.Command("docker", "exec", containerName, "/bin/sh")
if err := cmd.Run(); err == nil {
fmt.Println("Warning:", containerName, "does not support /bin/bash, using /bin/sh")
runInteractiveCommand("docker", "exec", "-it", containerName, "/bin/sh")
} else {
fmt.Println("Error: Unable to spawn shell session for", containerName)
os.Exit(1)
}
}

case "upgrade":
runCommandSequence(
[]string{"docker", "compose", "down"},
[]string{"docker", "compose", "pull"},
[]string{"docker", "compose", "up", "-d"},
)
fmt.Println("Complete")

default:
usage()
os.Exit(2)
}
}

func usage() {
fmt.Println("usage: dutil [reload|rebuild|networks|ps|psg] [container name]")
fmt.Println(" net|network|networks\n\t\t Returns the list of docker networks")
fmt.Println(" ps|psg\n\t\t If given a container name, perform a search for it. psg performs a grep instead against docker ps -a")
fmt.Println(" rebuild\n\t\t Performs a docker compose down, build, and up, detatched")
fmt.Println(" reload\n\t\t Performs a docker compose down and up, detatched")
fmt.Println(" shell\n\t\t Runs docker exec -it against a given container name and opens a bash shell (as fallback, use /bin/sh).")
fmt.Println("Part of the _subtype common library")
}

func runCommand(command string, args ...string) {
cmd := exec.Command(command, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Run(); err != nil {
fmt.Println("Error executing command:", err)
os.Exit(1)
}
}

func runInteractiveCommand(command string, args ...string) {
cmd := exec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Run(); err != nil {
fmt.Println("Error executing interactive command:", err)
os.Exit(1)
}
}

func runCommandSequence(commands ...[]string) {
for _, cmdArgs := range commands {
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Run(); err != nil {
fmt.Println("Error executing command sequence:", err)
os.Exit(1)
}
}
}
120 changes: 120 additions & 0 deletions bin/dutil.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/bin/bash
# Author: Andrew Subowo
# docker compose based utils -- these can be translated into aliases. It's not that fancy.
# These are things that I somewhat do on a more frequent basis.
# @_subtype / subtype / 2024

# TODO: Figure out how to determine if this was called via source or not or blah blah blah
# # If this script is interrupted, just return the user to the pwd they were in
# INITDIR=$(pwd)
# trap "cd $INITDIR" EXIT


function usage() {
echo "usage: dutil [reload|rebuild|networks|ps|psg] [container name]"
echo -e " net|network|networks\n\t\t Returns the list of docker networks"
echo -e " ps|psg\n\t\t If given a container name, perform a search for it. psg performs a grep instead against docker ps -a"
echo -e " rebuild\n\t\t Performs a docker compose down, build, and up, detatched"
echo -e " reload\n\t\t Performs a docker compose down and up, detatched"
echo -e " shell\n\t\t Runs docker exec -it against a given container name and opens a bash shell (as fallback, use /bin/sh)."
echo "Part of the _subtype common library"
exit 2
}

# TODO: EVENTUALLY MAKE THIS COMPLETELY STANDALONE(?) Should be able to detect if core is installed or not
# Shouldn't have to enforce utilization of the common core, but eh
# Check and source some methods that are included as part of the common core
function checkAndSourceCommonCore() {
# If the installer was used, the common library should be symlinked/available
COMMON_CORE_INSTALL="$( cd $(dirname $(dirname "$(readlink -f "$0")")) && pwd)"
if [ ! -d $COMMON_CORE_INSTALL ]; then
echo "Could not locate the common core library at $COMMON_CORE_INSTALL. Please consider re-pulling the repository"
exit 1
else
source $COMMON_CORE_INSTALL/utils/logging.sh
source $COMMON_CORE_INSTALL/utils/corefunc.sh
source $COMMON_CORE_INSTALL/utils/dockerinit.sh
fi
}

# Main utility function
# Wrap it all into a function in case someone somehow partially downloads the file
function dutil() {
# Get current pwd
checkAndSourceCommonCore
CHECK_COMMANDS dockerinit warn ok error

if [ -z $1 ]; then
usage
fi

# TODO: Add v1 support, maybe.
if ! docker compose version &> /dev/null; then
echo "Docker compose v2 is not installed"
return 1
fi

case $1 in
init)
if ! command -v dockerinit &> /dev/null; then
echo "dockerinit is not present"
return 1
else
dockerinit
fi
;;
net|network|networks)
docker network ls
;;
ps)
if [ -z $2 ]; then
docker ps -a
else
docker ps -a -f name=$2
fi
;;
psg)
if [ -z $2 ]; then
docker ps -a
else
docker ps -a | grep $2
fi
;;
rebuild)
#TODO: See if compose file has a build context?
docker compose down && docker compose build . && docker compose up -d
;;
reload)
if [ ! -z $2 ]; then #docker compose up and down a given service
docker compose -f $2 down && docker compose -f $2 up -d
else
docker compose down && docker compose up -d
fi
;;
shell)
if [ -z $2 ]; then
usage
error "Missing container name"
else
if docker exec $2 /bin/bash > /dev/null 2>&1; then
ok "Starting /bin/bash in $2"
docker exec -it $2 /bin/bash
elif docker exec $2 /bin/sh > /dev/null 2>&1; then
warn "$2 does not support /bin/bash, using /bin/sh"
docker exec -it $2 /bin/sh
else
error "Unable to spawn shell session for $2"
return 1
fi
fi
;;
upgrade)
docker compose down && docker compose pull && docker compose up -d && ok "Complete"
;;
*)
usage
;;
esac
}

dutil "$@"
22 changes: 22 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
# Author: Andrew Subowo
# @_subtype / subtype / 2024
# Installation script to install dutil into /usr/local/bin


# Install dutil via a symlink to ./bin/dutil.sh is here. That way we can also sorta kinda maybe import the other helper utils
echo "Installing docker utilities"
echo "Creating 'dutil' symlink under /usr/local/bin"
## TODO: Check for updates?
# Get directory where this file is currently
SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
ln -sf $SCRIPTPATH/bin/dutil.sh /usr/local/bin/dutil && echo "Installed as dutil under /usr/local/bin/dutil" || echo "There was an error creating the symlink" && exit 1

# Not going to fix this right now
# echo "Running aliases"

# if [[ -x $SCRIPTPATH/setupshell.sh ]]; then
# . $SCRIPTPATH/setupshell.sh
# else
# echo "Couldn't find the setupshell script, or the file isn't executable"
# fi
7 changes: 7 additions & 0 deletions setupshell.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
# Script to init a shell with some handy aliases, if they haven't already

alias please='sudo'
alias mkdir='mkdir -pv'
alias mount='mount | column -t'
alias showports='netstat -nulpta'
Loading