You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/designs/design.md
+28Lines changed: 28 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -127,6 +127,34 @@ In the configure stage, layers should register the data that other layers might
127
127
128
128
The configure stage is especially useful if a layer wants to make changes to another layer but still requires the other layer to have configured the emulator first. Currently, this is used in the `ReverseDomainName` and `CymruIpOrigin` service, both of which create a new zone in the `DomainName` service. They do so in the configure stage, as `DomainName` compiles the `Zone` data structure to zone files in the render stage, and additional zone added after the render stage won't be included in the final output.
129
129
130
+
#### Customizing layers and Entities (option system)
131
+
132
+
SEED has a rich option system which allows for fine grained overrides of global default settings.
133
+
134
+
Its workings are basically as follows:
135
+
136
+
137
+
Options can be anything from boolean flags to numerical configuration parameters and are best thought of as just a strong type for key-value pairs (where the value is mutable, but the key isn't). Moreover each option carries with it the notion of supported modes. That is, whether it can be changed only at compile/build-time (because its value gets baked into the container image i.e. as a config file entry ) and any reconfiguration requires a re-compile and image rebuild or whether its existence extends into the runtime (i.e. as a container ENV variable ) and its reconfiguration requires a mere container restart. Some options i.e. Feature Flags might require the installation of additional software on the target node(the `Customizable`) for their implementation and thus will be strickly limited to build-time.
138
+
139
+
140
+
Layers inherit `DynamicConfigurable` and can thus return a set of supported options (`getAvailableOptions()`).
141
+
Configurables are the only place to retrieve options, as they cannot just be constructed by the users arbitrarily (i.e. Layers are only considering their own set of options with known predefined keys/names and ignore any unknowns i.e. from other Layers ).
142
+
143
+
The counterpart of configurables are `Customizables`, objects that can be configured by options. The API of Customizables allows the setting and querying of options at a certain `Scope`(which can i.e. be Global, on AS level, by NodeType like 'All-Routers', or even specific to an individual Node ). If unspecified the scope for both option setters and getters will default to the scope that is most specific (narrow) to the respective Customizable (i.e. AS or Node). This distinctive Scope value can be obtained from any Customizable through the identically named getter function( i.e. for an AutonomousSystem AS150 `scope()` will return `Scope(ScopeTier.AS, as_id=150, node_type=ScopeType.ANY)` ). As a rule of thumb, `Scope`s are technical and users shouldn't have to deal with them during 'daily buisiness' because all methods provide sensible defaults. But do not shy away though.
144
+
145
+
Some Customizables are aggregates and own other Customizables (i.e. ASes are a collection of Nodes) to whom they can inherit their options (parent to child) with the `handDown()` method.
146
+
147
+
The base class impl of `DynamicConfigurable` calls the `prepare()` hook just before its configuration (`configure` call) in which its sets all its available options on all the Nodes in the emulation as global defaults. If a node already has more specific overrides for an option ( i.e. because it inherited its local ASes settings that deviate from the global default or the user explicitly changed the option on this particular node) this will be a NoOp (more specific settings preceede). The Base layer (which is configured very first) makes sure that all options which might have been overridden on AS level by the user are inherited down to the resident nodes of that AS.
148
+
149
+
The resulting state of option settings after the `prepare` call will be the basis for node configuration in the subsequent `configure` step.
150
+
As a result of this it should be avoided to create new nodes during configuration(they'd sidestep/slip customization).
151
+
152
+
###### Options Guidelines and Best Practices
153
+
154
+
If you ever catch yourself adding configuration getters/setters to your layer (i.e. `setLoglevel()`) what you should be doing instead (rather than bloating the interface of your class) is to just add an option `LOGLEVEL` and pass sensible default values to the constructor of your layer.
155
+
156
+
A good way to provide access to your layer's options is i.e. a factory method which returns an error, when asked for options with an unknown key.
157
+
130
158
## Graphing
131
159
132
160
Serval classes of the emulator offer graphing options to convert the topologies to graphs. These classes are:
In addition to the SCION layers we instantiate the `Ibgp` and `Ebgp` layers for BGP as well as `Ospf` for AS-internal routing.
38
+
Note that the ScionRouting layer accepts global default values for options as constructor parameters.
39
+
We use it here to decrease the loglevel from 'debug' to 'error' for all SCION distributables in the whole emulation if not overriden elsewhere. Also we change the mode for `LOGLEVEL` from `BUILD_TIME`(default) to `RUN_TIME` in the same statement.
40
+
Lastly we specify (as a global default for all nodes) that we want to use a local build of the `v0.12.0` SCION stack, rather than the 'official' `.deb` packages (`SetupSpecification.PACKAGES`). The SetupSpec is just an ordinary option and be overriden for ASes or individual nodes just like any other.
25
41
26
42
## Step 2: Create isolation domains and internet exchanges
27
43
@@ -40,7 +56,8 @@ We have two ISDs and four internet exchanges this time.
40
56
41
57
## Step 3: Create autonomous systems
42
58
43
-
The topology we create contains the two core ASes 150 and 160. AS 150 is in ISD 1 and AS 160 is in ISD 2. ISD 1 has three additional non-core ASes. In ISD 2 we have one non-core AS.
59
+
The topology we create contains the two core ASes 150 and 160. AS 150 is in ISD 1 and AS 160 is in ISD 2.
60
+
ISD 1 has three additional non-core ASes. In ISD 2 we have one non-core AS.
AS 150 contains four internal network connected in a ring topology by the four border routers br0, br1, br2, and br3. There are two control services cs1 and cs2. We will use br0 to connect to the core of ISD 2 (i.e., AS 160) and the other border routers to connect to customer/child ASes 151, 152, and 153.
- DISABLE_BFD option is changed from default BUILD_TIME to RUNTIME_MODE (the value is left at the default: 'true') on all SCION border routers of AS150
102
+
- LOGLEVEL is increased from global default 'error' to 'debug' only for node '150_br0' and the mode set to RUN_TIME
103
+
- SERVE_METRICS option is enabled on node '150_br1'.
104
+
This node will serve collected Prometheus metrics of the SCION border router distributable on port 30442.
105
+
If this behaviour is no longer desired it can turned of at RUN_TIME again, without re-compile and container rebuild
106
+
107
+
As a result the following `.env` file will be generated next to the `docker-compose.yml` containing all instantiated `RUN_TIME` options:
108
+
```
109
+
LOGLEVEL_150_BR0=debug
110
+
DISABLE_BFD_150_BRDNODE=true
111
+
SERVE_METRICS_150_BR1=true
112
+
LOGLEVEL_150=info
113
+
LOGLEVEL=error
114
+
```
115
+
These variables are referenced from the `docker-compose.yml` file:
116
+
117
+
```
118
+
brdnode_150_br0:
119
+
...
120
+
environment:
121
+
- LOGLEVEL=${LOGLEVEL_150_BR0}
122
+
- DISABLE_BFD=${DISABLE_BFD_150_BRDNODE}
123
+
124
+
brdnode_150_br1:
125
+
...
126
+
environment:
127
+
- LOGLEVEL=${LOGLEVEL_150}
128
+
- SERVE_METRICS=${SERVE_METRICS_150_BR1}
129
+
- DISABLE_BFD=${DISABLE_BFD_150_BRDNODE}
130
+
131
+
brdnode_150_br2|3:
132
+
...
133
+
environment:
134
+
- LOGLEVEL=${LOGLEVEL_150}
135
+
- DISABLE_BFD=${DISABLE_BFD_150_BRDNODE}
136
+
csnode_150_cs1:
137
+
...
138
+
environment:
139
+
- LOGLEVEL=${LOGLEVEL_150}
140
+
141
+
brdnode_151_br0:
142
+
...
143
+
environment:
144
+
- LOGLEVEL=${LOGLEVEL}
145
+
```
146
+
Note that each service has in its `environment:` section (only) the runtime variables that apply to it (that is: match its ASN, NodeType or NodeIdentity).
0 commit comments