Directory Structure
March 10, 2022 · View on GitHub
Up until this point, we have been dealing with a very simple directory structure. In the wild, Lighthouse trees usually have more depth, which grants more flexibility when constructing data for different environments.
For instance, take this directory tree:
deploy/
├── lighthouse.edn
├── lib
│ ├── nginx.edn
│ └── pod.edn
├── prod
│ └── nginx.edn
├── qa
│ └── nginx.edn
└── staging
└── nginx.edn
As before, the lighthouse.edn file anchors the root of the data files.
There are several nginx.edn files. The one in the lib directory looks like this:
{def/from ["pod"]
def/name "nginx"
:spec {:containers
{ref/name
{:image "nginx:1.14.2"
:ports {:http {:container-port 80}}}}}}
And the nginx.edn file in each environment directory (prod, qa,
staging) looks like this:
{def/from ["nginx"]}
Because there is usually so much sharing between environments, the "leaf" libraries tend to be very short and only contain metadata overrides.
Multiple lib directories
Lighthouse looks for libraries at each level up the directory tree until it
reaches the lighthouse.edn file.
For instance, if we want the nginx pod to be in a different Kubernetes
namespace in prod, we can accomplish this by adding a lib directory inside
prod with a library with the same name as the base library (nginx.edn):
├── lib
│ ├── nginx.edn
│ └── pod.edn
├── prod
│ ├── lib
│ │ └── nginx.edn
│ └── nginx.edn
And if that prod/lib/nginx.edn file looks like this:
{:metadata {:namespace "prod-ns"}}
When the prod nginx is built (with lh build prod/nginx.edn), the
resulting manifest is:
# ------------------------------------------------------------
# AUTO-GENERATED FILE. ANY MANUAL CHANGES WILL BE OVERWRITTEN.
# ------------------------------------------------------------
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: prod-ns <-- new line added because of prod nginx library
spec:
containers:
- image: nginx:1.14.2
name: nginx
ports:
- containerPort: 80
name: http
Lighthouse accomplished this by merging the data in this order:
lib/pod.ednlib/nginx.ednprod/lib/nginx.ednprod/nginx.edn
What if we wanted the namespace to be prod-ns for all pods in the prod
environment? Well, then we could rename prod/lib/nginx.edn to
prod/lib/pod.edn, and anything that specifies a parent library of pod
(directly or transitively) will see that data merged in.
In this case, the merging is in this order:
lib/pod.ednprod/lib/pod.ednlib/nginx.ednprod/nginx.edn
This highlights the fact that libraries of the same name at different levels are merged together, before they are merged into their child libraries.