-
Notifications
You must be signed in to change notification settings - Fork 243
Dev: Code architecture
A go context
is created at the very beginning of the execution of the go program, and is transmitted to the whole program.
import (
"context"
"github.com/redhat-developer/odo/pkg/config"
envcontext "github.com/redhat-developer/odo/pkg/config/context"
segment "github.com/redhat-developer/odo/pkg/segment/context"
)
func main() {
// Create a context ready for receiving telemetry data
// and save into it configuration based on environment variables
ctx := segment.NewContext(context.Background()) ❶
envConfig, err := config.GetConfiguration()
if err != nil {
util.LogErrorAndExit(err, "")
}
ctx = envcontext.WithEnvConfig(ctx, *envConfig) ❷
Thanks to ctx = segment.NewContext(ctx)
(❶), the context is ready to accept data to be sent to the telemetry platform.
CLI and business layers can use functions provided by the pkg/segment/context
package, to set data to be sent: SetComponentType
, SetClusterType
, etc.
For example, the CLI layer for the odo dev
command uses this code to set the component type to be sent to the telemetry:
scontext.SetComponentType(ctx, component.GetComponentTypeFromDevfileMetadata(devFileObj.Data.GetMetadata()))
At the end of the execution of a command, the telemetry data is collected and sent, using the odo telemetry
command as sub-process (see the use of the function startTelemetry
in genericclioptions.GenericRun
).
odo
accepts some environment variables to configure its behaviour.
Thanks to ctx = envcontext.WithEnvConfig(ctx, *envConfig)
(❷), values of these environment variables are accessible from the context
using the function GetEnvConfig
from the pkg/config/context
package. The value returned by this function
is a structure containing pointers to values. A pointer points to nil when the associated environment variable is not defined
and points to the value of the variable, when defined.
For example, to get the value of the PODMAN_CMD
environment variable, or "podman"
if the environment variable is not defined:
podmanCmd := pointer.StringDeref(envcontext.GetEnvConfig(ctx).PodmanCmd, "podman")
These values being injected in the context before calling the NewCmdOdo(ctx, ...)
function, they are available
when defining the odo commands and flags.
These values are also available when a specific command is executed, from the ctx
parameter passed to the Complete
, Validate
and Run
methods of the command.
Values defining the context on which odo
is executed are stored in the context, and are accessible with specific functions from the pkg/odo/context
package:
- Application name (always
"app"
for now), withGetApplication(ctx)
, - Directory on which odo is executed, with
GetWorkingDirectory(ctx)
, - Path of the devfile found in the working directory, with
GetDevfilePath(ctx)
, - The content of the Devfile found in the working directory, with
GetDevfileObj(ctx)
, - The name of the Devfile component (based on Devfile metadata name or, if not defined, the current directory name), with
GetComponentName(ctx)
, - The current namespace of the Kubernetes/Openshift cluster, with
GetNamespace(ctx)
.
These values are set in genericclioptions.GenericRun
, and so:
- they are available when a specific command is executed, from the
ctx
parameter passed to theComplete
,Validate
andRun
methods of the command. - they are not available when defining the odo commands and flags.
These values are stored into the context only if they make sense for the executed command, based on the dependencies declared for the command using clientset.Add
:
- Namespace is stored only in the context if the KUBERNETES dependency is requested.
- Working directory, Devfile path, defile content and component name are stored in the context if the FILESYSTEM dependency is requested.
Some flags are common to several commands. The values of these flags are stored in the context, and are accessible with specific functions from the pkg/odo/commonflags/context
package.
- If JSON output is requested with
-o json
flag, accessible withIsJsonOutput(ctx)
, - Which platform is targeted with
--run-on *platform*
, accessible withGetRunOn(ctx)
, - Which variables are passed with
--var
and/or--var-file
flags, accessible withGetVariables(ctx)
.
These values are set in genericclioptions.GenericRun
, and so:
- they are available when a specific command is executed, from the
ctx
parameter passed to theComplete
,Validate
andRun
methods of the command. - they are not available when defining the odo commands and flags.
These values are stored into the context only if they make sense for the executed command, based on the dependencies declared for the command using clientset.Add
:
- Variables are stored only if FILESYSTEM dependency is requested.
A dependency injection system gives access to modules by the commands. A command needs to register the modules it needs to access with the function clientset.Add
.
The dependency injection system is implemented in pkg/odo/genericclioptions/clientset
. Modules are registered there, as well as dependencies between modules (a module can declare it needs access to other modules).
The dependency injection system creates at startup one (and only one) instance of each module needed by the invoked command, directly or indirectly, and injects these dependencies into the command (using the SetClientset method) and the modules (using the helper function NewClient(deps …)
provided by each module).