Customize the Geodesic Shell
Problem
Geodesic solves a lot of problems teams have, but it’s opinionated and probably doesn’t work exactly the way you like your shell to work. Maybe you would like more alias
definitions, or maybe you don’t like our alias
definitions. Maybe you want to change the colors of ls
output (e.g. DIR_COLORS
) or you just can’t stand using vim
as the default editor.
Solution
Our own developers couldn’t agree on what the best look-and-feel was for geodesic
so we added support for customizations. This is how to customize Geodesic at launch time.
Several features of Geodesic can be customized at launch time (rather than during the build of the Docker image) so that people can share an image yet still have things set up the way they like. This document describes how to configure the customization.
WARNING
One of the key benefits of Geodesic is that it provides a consistent environment for all users regardless of their local machine. It eliminates the "it works on my machine" excuse. While these customization options can be great productivity enhancements as well as provide the opportunity to install new features to try them out before committing to installing them permanently, they can also create the kind of divergence in environments that brings back the "it works on my machine" problem.
Therefore, we have included an option to disable the customization files: the preferences, the overrides, and the docker environment files. Simply set and export the host environment variable $GEODESIC_CUSTOMIZATION_DISABLED
to any value other than "false" before launching Geodesic.
The way it works is users can place bash shell scripts on their host computer, which are read in either at the start of the bash
profile script processing or at the end of it. These shell scripts can set up environment variables, command aliases, shell functions, etc., and through setting environment variables, can cause Geodesic to enable or disable certain features.
Users can also choose whether to have a single bash
history file for all containers or to have separate history files. This is convenient if working with multiple geodesic containers.
Root Directory for Configuration
All configuration files are stored under $GEODESIC_CONFIG_HOME
, which defaults to /localhost/.geodesic
. At this time, /localhost
is mapped to the host $HOME
directory and this cannot be configured yet, so all configuration files must be under $HOME
, but within that limitation, they can be placed anywhere. So if you set $GEODESIC_CONFIG_HOME
to /localhost/work/config/geodesic
, then files would go in ~/work/config/geodesic/
and below on your Docker host machine.
Resources
There are currently 3 resources used for configuration:
-
Preferences, which are shell scripts loaded very early in the launch of the Geodesic shell.
-
Overrides, which are shell scripts loaded very late in the launch of the Geodesic shell.
-
Bash
History Files, which storebash
command line history.
Additionally, when Geodesic exits normally, it will run the host command geodesic_on_exit
if it is available. This is intended to be a script that you write and install anywhere on your PATH to do whatever cleanup you want. For example, change the window title.
Both preferences and overrides can be either a single file, named preferences
and overrides
respectively, or can be a collection of files in directories named preferences.d
and overrides.d
. If they are directories, all the visible files in the directories will be sourced, except for hidden files and files with names matching the GEODESIC_AUTO_LOAD_EXCLUSIONS
regex, which defaults to (~|.bak|.log|.old|.orig|.disabled)$
.
bash
history is always stored in a single file named history
, never a directory of files nor files with any other name. If you want to use a separate history file for one Geodesic-based Docker image not shared by other Geodesic-based Docker images, you must create an empty history
file in the image-specific configuration directory (see below).
Configuration by File Placement
Resources can be in several places and will be loaded from most general to most specific, according to the name of the docker container image.
-
The most general resources are the ones directly in
$GEODESIC_CONFIG_HOME
. These are applied first. To keep the top-level directory less cluttered and to avoid name clashes, you can put them in a subdirectory nameddefaults
. If that subdirectory exists, thenGEODESIC_CONFIG_HOME
itself is not searched. -
The
DOCKER_IMAGE
name is then parsed. Everything before the final/
is considered the "company" name and everything after is, following the Cloudposse reference architecture, referred to as the "stage" name. So for theDOCKER_IMAGE
namecloudposse/geodesic
, the company name iscloudposse
and the stage name isgeodesic
-
The next place searched for resources is the directory with the same name as the "company". In our example, that would be
~/.geodesic/cloudposse
. Resources here would apply to all containers from the same company. -
The next place searched for resources is the directory with the same name as the "stage", which is generally the name of the project. In our example, that would be
~/.geodesic/geodesic
. Resources here would apply to all containers with the same base name, perhaps various forks of the same project. -
The final place searched is the directory with the full name of the Docker image:
$GEODESIC_CONFIG_HOME/$DOCKER_IMAGE
, i.e.~/.geodesic/cloudposse/geodesic
. Files here are the most specific to this container.
By loading them in this order, you can put your defaults at one level and then override/customize them at another, minimizing the amount of duplication needed to customize a wide range of containers.
Usage details
Preferences and Overrides are loaded in the order specified above and all that are found are loaded. For history files, only the last one found is used. To start keeping separate history, just create an empty history file in the appropriate place.
While Preferences and Override files themselves must be bash
scripts and will be directly loaded into the top-level Geodesic shell, they can of course call other programs. You can even use them to pull configurations out of other places.
Symbolic links must be relative if you want them to work both inside Geodesic and outside of it. Symbolic links that reference directories that are not below $HOME
on the host will not work.
When possible, Geodesic mounts the host $HOME
directory as /localhost
and creates a symbolic link from $HOME
to /localhost
so that files under $HOME
on the host can be referenced by the exact same absolute path both on the host computer and inside Geodesic. For example, if the host $HOME
is /Users/fred
, then /Users/fred/src/example.sh
will refer to the same file both on the host and from inside the Geodesic shell.
In general, you should put most of your customization in the Preferences files. Geodesic (usually) takes care to respect and adapt to preferences set before it starts adding on top of them. The primary use for overrides is if you need the results of the initialization process as inputs to your configuration, or if you need to undo something Geodesic does not yet provide a configuration option for not doing in the first place.
Example: Adding Aliases and Environment Variables
Add the following to ~/.geodesic/defaults/preferences
# Add an alias for `kubectl`
alias kc='kubectl'
alias ll='ls -al'
# Add an alias to easily run `geodesic` inside of kubernetes
alias debugpod='kubectl run remote-shell-example --image=public.ecr.aws/cloudposse/geodesic:latest-debian --rm=true -i -t --restart=Never --env="BANNER=Geodesic" -- -l'
export AWS_ASSUME_ROLE_TTL=8h
export AWS_CHAINED_SESSION_TOKEN_TTL=8h
if [[ "$USE_AWS_VAULT" = "true" ]] ; then
export AWS_VAULT_SERVER_ENABLED=true
export AWS_VAULT_ASSUME_ROLE_TTL=8h
# Install the Debian package from cloudposse/packages for `aws-vault`
apt-get install -y aws-vault
fi
Example: Customize the command prompt
You can set each of the 4 glyphs used by the command line prompt, plus the host file system designator, individually:
-
ASSUME_ROLE_ACTIVE_MARK
is the glyph to show when you have AWS credentials active. Defaults to a green, bold, '√' SQUARE ROOT (looks like a check mark):$'\u221a'
-
ASSUME_ROLE_INACTIVE_MARK
is the glyph to show when you do not have AWS credentials active. Defaults to a red, bold, '✗' BALLOT X:$'\u2717'
-
BLACK_RIGHTWARDS_ARROWHEAD
is the glyph at the end of the prompt. The troublesome default is '⨠' Z NOTATION SCHEMA PIPING:$'\u2a20'
-
BANNER_MARK
is the glyph at the start of the first line of a 2-line prompt that introduces theBANNER
text. Defaults to '⧉', TWO JOINED SQUARES:$'\u29c9'
-
PROMPT_HOST_MARK
is added to the command line when the current working directory is on the host computer (via a bind mount) and not in the container. Defaults to '(HOST)' with "HOST" in red bold. Disable this feature by settingexport PROMPT_HOST_MARK=""
.
The default BLACK_RIGHTWARDS_ARROWHEAD
is from the Unicode Supplemental plane and therefore may be missing from some systems. You can use ->
instead by adding
export BLACK_RIGHTWARDS_ARROWHEAD="->"
to your ~/.geodesic/defaults/preferences
file.
Cautions:
-
You can set these variables to multiple characters, and use ANSI escape codes to change their colors, but in order for command line editing to continue to work properly, any non-printing characters must be escaped. We have had the best luck with starting the escape with
$'\x01'
and ending it with$'\x02'
, but there a couple of other, similar options. If you fail to do this, or do it incorrectly, your cursor will be incorrectly positioned when you edit a command line from your history and what you see will not be what is executed. -
Command line editing can also be affected by "ambiguous width characters". Unicode characters can be "narrow" or "wide" or "ambiguous". In practice in Roman (e.g. English) scripts, a "wide" character takes up the space of 2 "narrow" characters, and the standard Roman letters are all narrow. In older versions of Unicode, many Emoji are ambiguous width. If you use an ambiguous width character that prints wide but is interpreted as narrow, command line editing will suffer from incorrect cursor placement, as with non-printing characters above. This can be worked around by finding and selecting a preference such as "Treat ambiguous characters as wide" (if you can find such a preference), but we recommend just avoiding characters that cause problems.
Troubleshooting
If customizations are not being found or are not working as expected, you can set the host environment variable $GEODESIC_TRACE
to "custom" before launching Geodesic and a trace of the customization process will be output to the console.