Skip to content

Commit

Permalink
feat: Move more bash setup to python main (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
jarojasm95 authored Feb 1, 2025
1 parent e1aabb4 commit b6dc96b
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 137 deletions.
File renamed without changes.
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,5 @@ ARG POETRY_VIRTUALENVS_CREATE="false"
# Poetry needs this to find the venv we created
ARG VIRTUAL_ENV=/root/.venv
RUN poetry install --only main

ENV ALADDIN_CONTAINER=1
103 changes: 14 additions & 89 deletions aladdin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ ALADDIN_DEV=${ALADDIN_DEV:-false}
INIT=false
CLUSTER_CODE=${CLUSTER_CODE:-LOCAL}
NAMESPACE=${NAMESPACE:-default}
IS_TERMINAL=true
SKIP_PROMPTS=false
KUBERNETES_VERSION="1.27.13"

Expand All @@ -25,24 +24,6 @@ PATH="$ALADDIN_BIN":"$PATH"

source "$SCRIPT_DIR/shared.sh"

# Check for cluster name aliases and alias them accordingly
function check_cluster_alias() {
if [[ -z "${ALADDIN_CONFIG_DIR:-}" ]]; then
return 0
fi
cluster_alias=$(jq -r --arg key "$CLUSTER_CODE" '.cluster_aliases[$key]' "$ALADDIN_CONFIG_DIR/config.json")
if [[ $cluster_alias != null ]]; then
export CLUSTER_CODE=$cluster_alias
fi
}

function get_config_variables() {
LOCAL_CLUSTER_PROVIDER="none"
if [[ -f "$HOME/.aladdin/config/config.json" ]]; then
LOCAL_CLUSTER_PROVIDER=$(jq -r '.local_cluster_provider // "none"' $HOME/.aladdin/config/config.json)
fi
}

function get_host_addr() {
case "$OSTYPE" in
linux*) HOST_ADDR="172.17.0.1" ;;
Expand All @@ -53,7 +34,7 @@ function get_host_addr() {
function check_and_handle_init() {
# Check if we need to force initialization
local last_launched_file init_every current_time previous_run
last_launched_file="$HOME/.infra/last_checked_${NAMESPACE}_${CLUSTER_CODE}"
last_launched_file="$HOME/.aladdin/infra_k8s_check_${NAMESPACE}_${CLUSTER_CODE}"
# once per day
init_every=$((3600 * 24))
current_time="$(date +'%s')"
Expand All @@ -63,13 +44,6 @@ function check_and_handle_init() {
if [[ "$current_time" -gt "$((${previous_run:-0}+init_every))" || "$previous_run" -gt "$current_time" ]]; then
INIT=true
fi
if ! docker image inspect $ALADDIN_IMAGE &> /dev/null; then
readonly repo_login_command="$(jq -r '.aladdin.repo_login_command' "$ALADDIN_CONFIG_DIR/config.json")"
if [[ "$repo_login_command" != "null" ]]; then
eval "$repo_login_command"
fi
docker pull "$ALADDIN_IMAGE"
fi
# Handle initialization logic
local infra_k8s_check_args=""
if "$INIT"; then
Expand All @@ -79,22 +53,12 @@ function check_and_handle_init() {
if "$ALADDIN_MANAGE_SOFTWARE_DEPENDENCIES"; then
"$SCRIPT_DIR"/infra_k8s_check.sh $infra_k8s_check_args
fi
}

function set_cluster_helper_vars() {
IS_LOCAL="$(_extract_cluster_config_value is_local)"
if [[ -z "$IS_LOCAL" ]]; then
IS_LOCAL=false
fi

IS_PROD="$(_extract_cluster_config_value is_prod)"
if [[ -z "$IS_PROD" ]]; then
IS_PROD=false
fi

IS_TESTING="$(_extract_cluster_config_value is_testing)"
if [[ -z "$IS_TESTING" ]]; then
IS_TESTING=false
if ! docker image inspect $ALADDIN_IMAGE &> /dev/null; then
readonly repo_login_command="$(jq -r '.aladdin.repo_login_command' "$ALADDIN_CONFIG_DIR/config.json")"
if [[ "$repo_login_command" != "null" ]]; then
eval "$repo_login_command"
fi
docker pull "$ALADDIN_IMAGE"
fi
}

Expand Down Expand Up @@ -125,42 +89,14 @@ function pathnorm(){
}

function confirm_production() {
if $IS_TERMINAL ; then # if this is an interactive shell and not jenkins or piped input, then verify
echoerr "Script is running in a terminal. Let us make user aware that this is production";
>&2 echo -ne '\033[;31mYou are on production. Please type "production" to continue: \033[0m'; read -r
if [[ ! $REPLY = "production" ]]; then
echoerr 'Exiting since you did not type production'
exit 0
fi
else
echoerr "This is production environment. This script is NOT running in a terminal, hence supressing user prompt to type 'production'";
echoerr "Script is running in a terminal. Let us make user aware that this is production";
>&2 echo -ne '\033[;31mYou are on production. Please type "production" to continue: \033[0m'; read -r
if [[ ! $REPLY = "production" ]]; then
echoerr 'Exiting since you did not type production'
exit 0
fi
}

function handle_ostypes() {
case "$OSTYPE" in
jenkins*|linux*|darwin*) # Running on jenkins/linux/osx
true # use the default pathnorm
;;
cygwin*) # Cygwin under windows
function pathnorm(){
# Normalize the path, the path should exists
typeset abspath="$(cd "$1" ; pwd)"
echo "${abspath#/cygdrive}"
}
;;
win*|bsd*|solaris*) # Windows
echoerr "Not sure how to launch docker here. Exiting ..."
return 1
;;
*)
echoerr "unknown OS: $OSTYPE"
echoerr "Not sure how to launch docker here. Exiting ..."
return 1
;;
esac
}

function prepare_volume_mount_options() {
# if this is not production or staging, we are mounting kubernetes folder so that
# config maps and other settings can be customized by developers
Expand All @@ -178,7 +114,7 @@ function prepare_volume_mount_options() {
if "$ALADDIN_DEV" || "$IS_LOCAL"; then
if [[ -f "$HOME/.aladdin/config/config.json" ]]; then
HOST_DIR=$(jq -r .host_dir $HOME/.aladdin/config/config.json)
if [[ "$HOST_DIR" == null ]]; then
if [[ "$HOST_DIR" == "None" ]]; then
# defaults to osx
HOST_DIR="$HOME"
fi
Expand Down Expand Up @@ -245,11 +181,7 @@ function enter_docker_container() {
confirm_production
fi

FLAGS="--privileged --rm -i"
# Set pseudo-tty only if aladdin is being run from a terminal
if $IS_TERMINAL ; then
FLAGS+="t"
fi
FLAGS="--privileged --rm -it"

docker run $FLAGS \
`# Environment` \
Expand Down Expand Up @@ -290,9 +222,6 @@ while [[ $# -gt 0 ]]; do
-i|--init)
INIT=true
;;
--non-terminal)
IS_TERMINAL=false
;;
--skip-prompts)
SKIP_PROMPTS=true
;;
Expand All @@ -305,14 +234,10 @@ while [[ $# -gt 0 ]]; do
shift # past argument or value
done

set_cluster_helper_vars
get_host_addr
check_cluster_alias
get_config_variables
exec_host_command "$@"
exec_host_plugin "$@"
check_and_handle_init
handle_ostypes
prepare_volume_mount_options
prepare_ssh_options
enter_docker_container "$@"
13 changes: 10 additions & 3 deletions aladdin/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ def load_cluster_configs():


def load_cluster_config(cluster):
return load_config_from_file(f'{os.environ["ALADDIN_CONFIG_DIR"]}/{cluster}/config.json')
return load_config_from_file(
f'{os.environ["ALADDIN_CONFIG_DIR"]}/{cluster}/config.json'
)


def load_namespace_override_config(cluster, namespace):
Expand Down Expand Up @@ -54,8 +56,13 @@ def load_user_config() -> dict:
try:
return load_config_from_file(path)
except FileNotFoundError:
set_user_config_file({})
return {}
logger.warning("User config file not found, creating one with default values")
default_values = {
"config_repo": "git@github.com:fivestars/aladdin-config.git",
"plugin_repo": "git@github.com:fivestars/aladdin-plugins.git",
}
set_user_config_file(default_values)
return default_values


def set_user_config_file(config: dict):
Expand Down
44 changes: 32 additions & 12 deletions aladdin/env.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
"""
Module to configure environment variables used by Aladdin
"""
import os

import os
import pathlib
import subprocess
from contextlib import suppress
from pathlib import Path
from typing import Optional

from jmespath import search

from aladdin import __version__, config
from aladdin.lib import logging
from aladdin.lib.cluster_rules import ClusterRules

logger = logging.getLogger(__name__)

Expand All @@ -21,10 +23,14 @@ def configure_env():
user_config = {}
with suppress(FileNotFoundError):
user_config = config.load_user_config()
manage_software_dependencies: Optional[bool] = search("manage.software_dependencies", user_config)
manage_software_dependencies: Optional[bool] = search(
"manage.software_dependencies", user_config
)
os.environ["ALADDIN_MANAGE_SOFTWARE_DEPENDENCIES"] = str(
# default of True if not specified
True if manage_software_dependencies is None else manage_software_dependencies
True
if manage_software_dependencies is None
else manage_software_dependencies
).lower()

aladdin_config = {}
Expand All @@ -37,9 +43,22 @@ def configure_env():
# use the aladdin version as the image tag
os.environ["ALADDIN_IMAGE"] = "{}:{}".format(
search("aladdin.repo", aladdin_config) or config.ALADDIN_DOCKER_REPO,
__version__
__version__,
)

for key in [
"IS_LOCAL",
"IS_PROD",
"IS_TESTING",
]:
os.environ[key] = str(getattr(ClusterRules(), key.lower()))

for key, default_value in {
"local_cluster_provider": "rancher-desktop",
"host_dir": str(Path.home()),
}.items():
os.environ[key.upper()] = str(user_config.get(key, default_value))


def set_config_path() -> bool:
"""
Expand All @@ -48,10 +67,14 @@ def set_config_path() -> bool:
any aladdin command, so returning False should be preceded by some
user-friendly error statement about why we're exiting
"""
return set_repo_path("ALADDIN_CONFIG_DIR", "config_dir", "config_repo", required=True)
return set_repo_path(
"ALADDIN_CONFIG_DIR", "config_dir", "config_repo", required=True
)


def set_repo_path(env_key: str, dir_key: str, repo_key: str, required: bool = False) -> bool:
def set_repo_path(
env_key: str, dir_key: str, repo_key: str, required: bool = False
) -> bool:
"""
Function to set the "dir_key" env var
Uses git to fetch the latest revision of the repo specified under "repo_key"
Expand All @@ -64,7 +87,7 @@ def set_repo_path(env_key: str, dir_key: str, repo_key: str, required: bool = Fa
err_message = (
f"Unable to find {repo_key}. "
f"Please use 'aladdin config set {repo_key} "
"<git@github.com:{git_account}/{repo}.git>' "
"git@github.com:{git_account}/{repo}.git' "
f"to set {repo_key} repo"
)
try:
Expand Down Expand Up @@ -120,10 +143,7 @@ def set_repo_path(env_key: str, dir_key: str, repo_key: str, required: bool = Fa
we update git tags and checkout the latest revision
"""
cwd = remote_config_path
git_commands = [
"git fetch --tags --prune -f",
f"git checkout {__version__}"
]
git_commands = ["git fetch --tags --prune -f", f"git checkout {__version__}"]
for command in git_commands:
try:
subprocess.run(
Expand All @@ -138,7 +158,7 @@ def set_repo_path(env_key: str, dir_key: str, repo_key: str, required: bool = Fa
"Failed to fetch aladdin %s (%s) from remote: \n%s",
repo_key,
repo_value,
e.stderr.strip() or e.stdout.strip()
e.stderr.strip() or e.stdout.strip(),
)
return False

Expand Down
24 changes: 20 additions & 4 deletions aladdin/lib/arg_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import json
import os
import sys
import pkg_resources
from contextlib import suppress
from inspect import signature

import pkg_resources
from kubernetes import config as kube_config

from aladdin.config import PROJECT_ROOT
Expand Down Expand Up @@ -49,13 +49,14 @@ def container_command(func=None):
Decorator to wrap aladdin commands that
need to be run inside the aladdin container
"""

@functools.wraps(func)
def _wrapper(*args, **kwargs):
# using `CLUSTER_CODE` as tell-tale to know
# if we're "in" the aladdin container
if not os.getenv("CLUSTER_CODE"):
# using `ALADDIN_CONTAINER` as way to know if we're "in" the aladdin container
if not os.getenv("ALADDIN_CONTAINER"):
return bash_wrapper()
return func(*args, **kwargs)

if not func:
return container_command
return _wrapper
Expand All @@ -73,6 +74,7 @@ def get_bash_commands():
def add_command(parser, cmd=bash_cmd, help_msg=bash_help["help"]):
sub_parser = parser.add_parser(cmd, help=help_msg)
sub_parser.set_defaults(func=lambda args: bash_wrapper())

commands.append((bash_cmd, add_command))
return commands

Expand Down Expand Up @@ -148,3 +150,17 @@ def wrapper(*args, **kwargs):
if not func:
return expand_namespace
return wrapper


class EnvActionMixin:
def __call__(self, parser, namespace, values, option_string=None):
super().__call__(parser, namespace, values, option_string)
os.environ[self.dest] = str(getattr(namespace, self.dest))


class EnvStoreAction(EnvActionMixin, argparse._StoreAction):
pass


class EnvStoreTrueAction(EnvActionMixin, argparse._StoreTrueAction):
pass
Loading

0 comments on commit b6dc96b

Please sign in to comment.