Skip to content

Commit

Permalink
chore: debug APIC configuration and readme docs (#2112)
Browse files Browse the repository at this point in the history
## Description:
debug APIC configuration and readme docs

## Is this change user facing?
NO

## References (if applicable):
<!-- Add relevant Github Issues, Discord threads, or other helpful
information. -->

---------

Co-authored-by: Edgar Gomes <[email protected]>
Co-authored-by: Kevin Today <[email protected]>
Co-authored-by: mieubrisse <[email protected]>
  • Loading branch information
4 people authored Feb 5, 2024
1 parent 0ce0711 commit e707212
Show file tree
Hide file tree
Showing 39 changed files with 1,125 additions and 624 deletions.
6 changes: 6 additions & 0 deletions .run/APIC-remote-debug.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="APIC-remote-debug" type="GoRemoteDebugConfigurationType" factoryName="Go Remote" port="50103">
<option name="disconnectOption" value="ASK" />
<method v="2" />
</configuration>
</component>
59 changes: 55 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,10 @@ ktdev engine start --debug-mode
4. Then choose the "Engine-remote-debug" run configuration in the "run panel"
5. Press the "debug" button
<img src="./readme-static-files/goland-engine-debug-button.png" />
6. Use the debug panel to inspect the variables value and continue with the debug flow
<img src="./readme-static-files/goland-debug-panel.png" />
7. Make a call to the engine's server (you can use the Kurtosis CLI or Postman) in order to reach out the breakpoint in the code
8. You can debug the CLI and the Kurtosis engine's server at the same time by running it with `ktdebug` instead of `ktdev` mentioned in a previous step, remember to run both remote debug configuration in the Goland IDE.
6. Make a call to the engine's server (you can use the Kurtosis CLI or Postman) in order to reach out the breakpoint in the code
7. Use the debug panel to inspect the variables value and continue with the debug flow
<img src="./readme-static-files/goland-debug-panel.png" />
8. You can debug the CLI and the Kurtosis engine's server at the same time by running it with `ktdebug` instead of `ktdev` mentioned in a previous step, remember to run both remote debug configurations in the Goland IDE.
```bash
source ./scripts/set_kt_alias.sh
ktdebug engine start
Expand All @@ -453,6 +453,57 @@ scripts/port-forward-engine-debug.sh
ktdev gateway
```

For running Kurtosis APIC with Golang remote debug:
1. Run the main build script with the first argument `debug_mode` as true. This will generate a new Kurtosis APIC container image which will contain the `debug` suffix in the name.
```bash
scripts/build.sh true
```
2. Add the breakpoint in the line where you want to stop the cursor.
<img src="./readme-static-files/goland-apic-breakpoint.png" />
3. Run the Kurtosis engine in debug more or not depending on if you want to also debug the engine.
```bash
source ./scripts/set_kt_alias.sh
ktdev engine start --debug-mode

OR

ktdev engine start # you will have to build the engine in the regular way `engine/scripts/build.sh` if you choose this version
```
4. Add a new enclave in debug mode with the `enclave add` command and passing the `debug-mode` flag. This will create a new APIC container with the debug server port bounded and waiting for a connection.
IMPORTANT: You can only run one enclave in debug mode so far, if you want to run another one it will fail due the debug port is already in use,
```bash
ktdev enclave add --debug-mode
```
5. Then choose the "APIC-remote-debug" run configuration in the "run panel"
6. Press the "debug" button
<img src="./readme-static-files/goland-apic-debug-button.png" />
7. Find the APIC's GRPC server port in the host machine (you can check it in Docker Desktop or using the Docker CLI, it's the one bounded with the container's 7443 port)
8. Make a call to the APIC's server (you can use the Kurtosis CLI or Postman) in order to reach out the breakpoint in the code
9. Use the debug panel to inspect the variables value and continue with the debug flow
<img src="./readme-static-files/goland-debug-panel.png" />
10. You can debug the CLI, the Kurtosis engine's server and the Kurtosis APIC's server at the same time by running it with `ktdebug` instead of `ktdev` mentioned in a previous step, remember to run the three remote debug configurations in the Goland IDE.
```bash
source ./scripts/set_kt_alias.sh
ktdev engine start --debug-mode
ktdebug enclave add
```

Additional steps if you are debugging Kurtosis engine in K8s:

1. Upload the APIC's image for debug to the K8s cluster
```bash
# for example:
k3d image load kurtosistech/core:5ec6eb-dirty-debug
```
2. Run the port-forward script before pressing the debug button in Golang (in another terminal instance) to bind the host's port to the container's debug server port
```bash
scripts/port-forward-apic-debug.sh enclave-name
```
3. Do not forget to run the Kurtosis gateway after calling the APIC's server (in another terminal instance also)
```bash
ktdev gateway
```

</details>

<!-------- ONLY LINKS BELOW THIS POINT -------->
Expand Down
562 changes: 289 additions & 273 deletions api/golang/engine/kurtosis_engine_rpc_api_bindings/engine_service.pb.go

Large diffs are not rendered by default.

102 changes: 88 additions & 14 deletions api/golang/engine/lib/kurtosis_context/kurtosis_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ const (
validUuidMatchesAllowed = 1

portalIsRequired = true

defaultShouldAPICRunInDebugMode = false
runAPICInDebugMode = true
)

var (
Expand Down Expand Up @@ -105,10 +108,7 @@ func NewKurtosisContextFromLocalEngine() (*KurtosisContext, error) {
}

// Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext
func (kurtosisCtx *KurtosisContext) CreateEnclave(
ctx context.Context,
enclaveName string,
) (*enclaves.EnclaveContext, error) {
func (kurtosisCtx *KurtosisContext) CreateEnclave(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, error) {

createEnclaveArgs := newCreateEnclaveArgsWithDefaultValues(enclaveName)

Expand All @@ -125,12 +125,29 @@ func (kurtosisCtx *KurtosisContext) CreateEnclave(
return enclaveContext, nil
}

// Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext
func (kurtosisCtx *KurtosisContext) CreateProductionEnclave(
func (kurtosisCtx *KurtosisContext) CreateEnclaveWithDebugEnabled(
ctx context.Context,
enclaveName string,
) (*enclaves.EnclaveContext, error) {

createEnclaveArgs := newCreateEnclaveArgsWithDefaultValuesForDebugging(enclaveName)

response, err := kurtosisCtx.engineClient.CreateEnclave(ctx, createEnclaveArgs)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating an enclave with name '%v'", enclaveName)
}

enclaveContext, err := newEnclaveContextFromEnclaveInfo(ctx, kurtosisCtx.portalClient, response.EnclaveInfo)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating an enclave context from a newly-created enclave; this should never happen")
}

return enclaveContext, nil
}

// Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext
func (kurtosisCtx *KurtosisContext) CreateProductionEnclave(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, error) {

createEnclaveArgs := newCreateProductionEnclaveWithDefaultValues(enclaveName)

response, err := kurtosisCtx.engineClient.CreateEnclave(ctx, createEnclaveArgs)
Expand All @@ -146,6 +163,23 @@ func (kurtosisCtx *KurtosisContext) CreateProductionEnclave(
return enclaveContext, nil
}

func (kurtosisCtx *KurtosisContext) CreateProductionEnclaveWithDebugEnabled(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, error) {

createEnclaveArgs := newCreateProductionEnclaveWithDefaultValuesForDebugging(enclaveName)

response, err := kurtosisCtx.engineClient.CreateEnclave(ctx, createEnclaveArgs)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating an enclave with name '%v'", enclaveName)
}

enclaveContext, err := newEnclaveContextFromEnclaveInfo(ctx, kurtosisCtx.portalClient, response.EnclaveInfo)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating an enclave context from a newly-created enclave; this should never happen")
}

return enclaveContext, nil
}

// Docs available at https://docs.kurtosis.com/sdk/#getenclavecontextstring-enclaveidentifier---enclavecontextenclavecontext-enclavecontext
func (kurtosisCtx *KurtosisContext) GetEnclaveContext(ctx context.Context, enclaveIdentifier string) (*enclaves.EnclaveContext, error) {
enclaveInfo, err := kurtosisCtx.GetEnclave(ctx, enclaveIdentifier)
Expand Down Expand Up @@ -594,12 +628,32 @@ func newCreateEnclaveArgsWithDefaultValues(enclaveName string) *kurtosis_engine_
defaultApiContainerVersionTag := defaultApiContainerVersionTagStr
defaultApiContainerLogLevel := defaultApiContainerLogLevelStr
defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_TEST
shouldApicRunInDebugMode := defaultShouldAPICRunInDebugMode

createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{
EnclaveName: &enclaveName,
ApiContainerVersionTag: &defaultApiContainerVersionTag,
ApiContainerLogLevel: &defaultApiContainerLogLevel,
Mode: &defaultEnclaveMode,
EnclaveName: &enclaveName,
ApiContainerVersionTag: &defaultApiContainerVersionTag,
ApiContainerLogLevel: &defaultApiContainerLogLevel,
Mode: &defaultEnclaveMode,
ShouldApicRunInDebugMode: &shouldApicRunInDebugMode,
}

return createEnclaveArgs
}

func newCreateEnclaveArgsWithDefaultValuesForDebugging(enclaveName string) *kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs {

defaultApiContainerVersionTag := defaultApiContainerVersionTagStr
defaultApiContainerLogLevel := defaultApiContainerLogLevelStr
defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_TEST
shouldApicRunInDebugMode := runAPICInDebugMode

createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{
EnclaveName: &enclaveName,
ApiContainerVersionTag: &defaultApiContainerVersionTag,
ApiContainerLogLevel: &defaultApiContainerLogLevel,
Mode: &defaultEnclaveMode,
ShouldApicRunInDebugMode: &shouldApicRunInDebugMode,
}

return createEnclaveArgs
Expand All @@ -610,12 +664,32 @@ func newCreateProductionEnclaveWithDefaultValues(enclaveName string) *kurtosis_e
defaultApiContainerVersionTag := defaultApiContainerVersionTagStr
defaultApiContainerLogLevel := defaultApiContainerLogLevelStr
defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_PRODUCTION
shouldApicRunInDebugMode := defaultShouldAPICRunInDebugMode

createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{
EnclaveName: &enclaveName,
ApiContainerVersionTag: &defaultApiContainerVersionTag,
ApiContainerLogLevel: &defaultApiContainerLogLevel,
Mode: &defaultEnclaveMode,
ShouldApicRunInDebugMode: &shouldApicRunInDebugMode,
}

return createEnclaveArgs
}

func newCreateProductionEnclaveWithDefaultValuesForDebugging(enclaveName string) *kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs {

defaultApiContainerVersionTag := defaultApiContainerVersionTagStr
defaultApiContainerLogLevel := defaultApiContainerLogLevelStr
defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_PRODUCTION
shouldApicRunInDebugMode := runAPICInDebugMode

createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{
EnclaveName: &enclaveName,
ApiContainerVersionTag: &defaultApiContainerVersionTag,
ApiContainerLogLevel: &defaultApiContainerLogLevel,
Mode: &defaultEnclaveMode,
EnclaveName: &enclaveName,
ApiContainerVersionTag: &defaultApiContainerVersionTag,
ApiContainerLogLevel: &defaultApiContainerLogLevel,
Mode: &defaultEnclaveMode,
ShouldApicRunInDebugMode: &shouldApicRunInDebugMode,
}

return createEnclaveArgs
Expand Down
18 changes: 14 additions & 4 deletions api/golang/http_rest/api_types/api_types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 28 additions & 27 deletions api/golang/http_rest/server/engine_rest_api/engine_server.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions api/openapi/specs/kurtosis_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,10 @@ components:
mode:
$ref: "#/components/schemas/EnclaveMode"
description: Enclave mode, defaults to TEST
should_apic_run_in_debug_mode:
$ref: "#/components/schemas/ApiContainerDebugMode"
# This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod)
description: Whether the APIC's container should run with the debug server to receive a remote debug connection
required:
- enclave_name
- api_container_version_tag
Expand Down Expand Up @@ -869,6 +873,13 @@ components:
- STOPPED
- NON_EXISTENT

ApiContainerDebugMode:
type: boolean
default: false
enum:
- false
- true

EnclaveInfo:
type: object
properties:
Expand Down
4 changes: 4 additions & 0 deletions api/protobuf/engine/engine_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ message CreateEnclaveArgs {
optional string api_container_log_level = 3;

optional EnclaveMode mode = 4;

// Whether the APIC's container should run with the debug server to receive a remote debug connection
// This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod)
optional bool should_apic_run_in_debug_mode = 5;
}

enum EnclaveMode {
Expand Down
4 changes: 4 additions & 0 deletions api/rust/src/engine_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ pub struct CreateEnclaveArgs {
pub api_container_log_level: ::core::option::Option<::prost::alloc::string::String>,
#[prost(enumeration = "EnclaveMode", optional, tag = "4")]
pub mode: ::core::option::Option<i32>,
/// Whether the APIC's container should run with the debug server to receive a remote debug connection
/// This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod)
#[prost(bool, optional, tag = "5")]
pub should_apic_run_in_debug_mode: ::core::option::Option<bool>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ export declare class CreateEnclaveArgs extends Message<CreateEnclaveArgs> {
*/
mode?: EnclaveMode;

/**
* Whether the APIC's container should run with the debug server to receive a remote debug connection
* This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod)
*
* @generated from field: optional bool should_apic_run_in_debug_mode = 5;
*/
shouldApicRunInDebugMode?: boolean;

constructor(data?: PartialMessage<CreateEnclaveArgs>);

static readonly runtime: typeof proto3;
Expand Down
Loading

0 comments on commit e707212

Please sign in to comment.