Scenario: working with micro-services¶
In this scenerio we’ll see how Dodo Commands can be used to work with two micro-services. It’s probably over-kill to use Dodo Commmands in this simple scenario, but as the project grows bigger, it will start to be worth it. To keep it simple the services are not Dockerized.
Tip
In the tutorials we’ll assume that Bash is used. In some cases we will source the output of
a Dodo command using $(dodo <command>)
. In case you are curious what is being sourced, you can run
the command without $()
and source it manually on the command line.
If you are using the Fish shell, then you can use dodo <command> | source
instead of
$(dodo <command>)
. In that case, be sure to also run dodo global-config setting.shell fish
to tell Dodo Commands that you are using the fish shell.
Tip
Parts of the tutorial that give technical details or explain more advanced features are kept separate from the main text. To not be overwhelmed, it’s probably better to skip them on a first read.
Two simple micro-services¶
The first micro-service writes the time to a file in the /tmp
directory, whereas the second
micro-service runs a tail
command that tracks the contents of this file. The source code for these
services is found in part1/before
of the dodo-commands-tutorial <https://github.com/mnieber/dodo-commands-tutorial>`_
repository. We will go ahead and clone the code for this part of the tutorial:
cd /tmp
git clone https://github.com/mnieber/dodo-commands-tutorial.git
# Copy part 1 of the tutorial so that we can work with a short path
cp -rf ./dodo-commands-tutorial/part1/before ./tutorial
Let’s try out the services:
cd /tmp/tutorial/writer
# let this run for a few seconds... (or run it in a separate tab and keep it running)
make runserver
cd /tmp/tutorial/reader
# this will print some timestamps that were generated by the writer service
make runserver
Setting up an environment¶
The next step is to create a Dodo Commands environment for working with our project:
cd /tmp/tutorial
$(dodo env --init tutorial)
# Check that we are in the "tutorial" environment
dodo which
tutorial
# The project dir is where your project lives.
# In this case, it's the directory where we called 'dodo env --init'.
dodo which --project-dir
/tmp/tutorial
# The configuration directory is where the Dodo Commands configuration files
# for the environment are stored.
dodo which --config-dir
/tmp/tutorial/.dodo_commands
# The environment directory is where Dodo Commands stores all other information
# about your environment. Usually, you don't need to work with this directory directly.
dodo which --env-dir
~/.dodo_commands/envs/tutorial
# The (optional) python_env directory contains the virtual Python environment for your project.
# In this case, we don't have any
dodo which --python-env-dir
(nothing here)
Tip
If something goes wrong during the creation of the Dodo Commands environment then you can delete the /tmp/tutorial directory and try again. In this case, you should also run dodo env –forget tutorial and run the clean up steps that it prints out (for reasons of safety Dodo Commands does not run these cleanup steps automatically).
Working with the configuration¶
Each environment contains a set of configuration files:
# The main configuration file is called config.yaml
dodo which --config
/tmp/tutorial/.dodo_commands/config.yaml
# Let's take a look at the configuration file:
cat $(dodo which --config)
ROOT:
command_path:
- ~/.dodo_commands/default_project/commands/*
version: 1.0.0
When we print the contents of the configuration, we see that some extra values were added automatically. These values do not appear in the configuration file but they are available at run-time.
dodo print-config
ROOT:
env_name: tutorial
command_path:
- ~/.dodo_commands/default_project/commands/*
- /some/path/to/dodo_commands/dodo_system_commands
project_dir: /tmp/tutorial/part1
config_dir: /tmp/tutorial/part1/.dodo_commands
version: 1.0.0
Extending the configuration¶
You can extend the configuration with new keys:
# (bottom of) /tmp/tutorial/.dodo_commands/config.yaml
MAKE:
cwd: ${/ROOT/project_dir}/writer
Now, when we print the contents of the MAKE
section, we get:
dodo print-config MAKE
cwd: /tmp/tutorial/writer
We see that we can interpolate values. In this case ${/ROOT/project_dir}/writer
was
interpolated to /tmp/tutorial/writer
.
Tip
Run the dodo edit-config
command to open all files in the configuration directory
in an editor. Set the config_editor
field in the global configuration file
(~/.dodo_commands/config
) to the editor you wish to use (we recommend using gedit with the
Side Panel enabled).
Note
From here on, we will use the notation ${/FOO/bar} to refer to the bar
key in the FOO
section of the configuration file.
Adding an alias to run the writer service¶
We’ll now create a mk.py
script that can be used as an alias for running the writer service.
This alias will serve as a shortcut to running make in the directory of the writer service.
cd /tmp/tutorial
mkdir ./commands
touch ./commands/mk.py
Add the following code to mk.py
:
from dodo_commands import Dodo
Dodo.parser.add_argument("what")
Dodo.run(["make", Dodo.args.what], cwd=Dodo.get("/MAKE/cwd"))
Open /tmp/tutorial/.dodo_commands/config.yaml
and edit
${/ROOT/command_path}
so it looks like this:
ROOT:
command_path:
- ~/.dodo_commands/default_project/commands/*
- ${/ROOT/project_dir}/commands
Now when we run dodo
(without passing any arguments) we get a list of all
available commands, and mk
should be somewhere in that list.
To run the command, let’s use the --confirm
flag so we can check that everything
is looking good:
dodo mk runserver --confirm
(/tmp/tutorial/writer) make runserver
confirm? [Y/n]
We see that the command will run make runserver
in the /tmp/tutorial/writer
directory, great!
Using layers to run the reader and writer service¶
At the moment, the mk command operates on the writer service. What if we instead want to run the Makefile of the reader service?
As a first step to generalize our mk command we will move the ${/MAKE}
section to a new configuration file:
server.writer.yaml
. This file should therefore look like this:
# /tmp/tutorial/.dodo_commands/server.writer.yaml
MAKE:
cwd: ${/ROOT/project_dir}/writer
Then we add a similar file for the reader:
# /tmp/tutorial/.dodo_commands/server.reader.yaml
MAKE:
cwd: ${/ROOT/project_dir}/reader
Tip
Don’t forget to remove the MAKE section from the main Dodo configuration file. To edit this file, you can run (substituting your favourite editor) nano $(dodo which –config).
Next, we will add a LAYERS_GROUP
in the main configuration file:
# (bottom of) /tmp/tutorial/.dodo_commands/config.yaml
LAYER_GROUPS:
server:
- writer
- reader
Now when we call dodo writer.mk runserver
then Dodo Commands will look for a layer
that has the name writer
. It will find this layer in the server
group and load the
server.writer.yaml
layer:
dodo writer.mk runserver --confirm
(/tmp/tutorial/writer) make runserver
confirm? [Y/n]
Of course, to run the reader, we can use dodo reader.mk runserver
.
Detail sections¶
Open the adjacent tabs for more detail sections
We saw above the Dodo Commands applies some magic to find out what command you want to run based
on the prefixes that you use before the name of the command. To find out what is going on below
the surface, use the --trace
option to print the result of this translation process
(without running any commands). For example:
dodo reader.mk runserver --trace
['/usr/local/bin/dodo', 'mk', 'runserver', '--layer=server.reader.yaml']
This tells us that we are actually invoking the command dodo mk runserver --layer=server.reader.yaml
.
We can group commands in a menu so we can easily run them
in a tmux session. First, make sure that tmux is installed on your system.
Then, add a MENU
section to the configuration file like this:
# (bottom of) /tmp/tutorial/.dodo_commands/config.yaml
MENU:
commands:
server:
- dodo writer.mk runserver
- dodo reader.mk runserver
When we run dodo menu --tmux
we’ll open a tmux session that show the menu:
dodo menu --tmux 1 [server] - dodo writer.mk runserver 2 [server] - dodo reader.mk runserver Select one or more commands (e.g. 1,3-4) or type 0 to exit:
Type 1,2
to run both commands. They will open in separate windows inside the tmux screen.