diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e81368d29..1c15f0fe31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [0.70.6](https://github.com/kurtosis-tech/kurtosis/compare/0.70.5...0.70.6) (2023-03-28) + + +### Features + +* add search on docs ([#159](https://github.com/kurtosis-tech/kurtosis/issues/159)) ([f80d036](https://github.com/kurtosis-tech/kurtosis/commit/f80d0361435c99707291c0e96c0c308326343330)) +* integrate lsp with monrepo ([#223](https://github.com/kurtosis-tech/kurtosis/issues/223)) ([b5ed670](https://github.com/kurtosis-tech/kurtosis/commit/b5ed6707b1c3254cefcfa9201fb76ff1116dedce)) + + +### Bug Fixes + +* fix typo in reindex workflow ([#357](https://github.com/kurtosis-tech/kurtosis/issues/357)) ([8900ff2](https://github.com/kurtosis-tech/kurtosis/commit/8900ff230240487e40e706fccc3b8e32b1d1082f)) +* remove file paths from error message ([#256](https://github.com/kurtosis-tech/kurtosis/issues/256)) ([cb603d8](https://github.com/kurtosis-tech/kurtosis/commit/cb603d836772812d602bfb86736a8145b85162e1)) +* remove trailing errors after starlark execution ([724ac35](https://github.com/kurtosis-tech/kurtosis/commit/724ac355e8cf64a070c3d62a0f593399b5ef2dde)) +* remove trailing errors after starlark execution ([#257](https://github.com/kurtosis-tech/kurtosis/issues/257)) ([724ac35](https://github.com/kurtosis-tech/kurtosis/commit/724ac355e8cf64a070c3d62a0f593399b5ef2dde)) + ## [0.70.5](https://github.com/kurtosis-tech/kurtosis/compare/0.70.4...0.70.5) (2023-03-28) diff --git a/LICENSE.md b/LICENSE.md index 69b8aca9c6..48a168d2d9 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -3,7 +3,7 @@ Business Source License 1.1 Parameters Licensor: Kurtosis Technologies, Inc. -Licensed Work: Kurtosis 0.70.5 +Licensed Work: Kurtosis 0.70.6 The Licensed Work is (c) 2023 Kurtosis Technologies, Inc. Additional Use Grant: You may make use of the Licensed Work, provided that you may not use the Licensed Work for an Environment Orchestration Service. diff --git a/api/golang/kurtosis_version/kurtosis_version.go b/api/golang/kurtosis_version/kurtosis_version.go index bfd6edd1a6..4d12f4e6b2 100644 --- a/api/golang/kurtosis_version/kurtosis_version.go +++ b/api/golang/kurtosis_version/kurtosis_version.go @@ -9,6 +9,6 @@ const ( // !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!! // This is necessary so that Kurt Core consumers will know if they're compatible with the currently-running // API container - KurtosisVersion = "0.70.5" + KurtosisVersion = "0.70.6" // !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!! ) diff --git a/api/typescript/package.json b/api/typescript/package.json index a110527593..5305b2fffd 100644 --- a/api/typescript/package.json +++ b/api/typescript/package.json @@ -1,7 +1,7 @@ { "name": "kurtosis-sdk", "//": "NOTE: DO NOT UPDATE THIS VERSION MANUALLY - IT WILL BE UPDATED DURING THE RELEASE PROCESS!", - "version": "0.70.5", + "version": "0.70.6", "main": "./build/index", "description": "This repo contains a Typescript client for communicating with the Kurtosis Engine server, which is responsible for creating, managing and destroying Kurtosis Enclaves.", "types": "./build/index", diff --git a/api/typescript/src/kurtosis_version/kurtosis_version.ts b/api/typescript/src/kurtosis_version/kurtosis_version.ts index 61690ba019..83f3abe2bd 100644 --- a/api/typescript/src/kurtosis_version/kurtosis_version.ts +++ b/api/typescript/src/kurtosis_version/kurtosis_version.ts @@ -1,5 +1,5 @@ // !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!! // This is necessary so that Kurt Core consumers (e.g. modules) will know if they're compatible with the currently-running // API container -export const KURTOSIS_VERSION: string = "0.70.5" +export const KURTOSIS_VERSION: string = "0.70.6" // !!!!!!!!!!! DO NOT UPDATE! WILL BE MANUALLY UPDATED DURING THE RELEASE PROCESS !!!!!!!!!!!!!!!!!!!!!! diff --git a/docs/versioned_docs/version-0.70.6/changelog.md b/docs/versioned_docs/version-0.70.6/changelog.md new file mode 100644 index 0000000000..1c15f0fe31 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/changelog.md @@ -0,0 +1,377 @@ +# Changelog + +## [0.70.6](https://github.com/kurtosis-tech/kurtosis/compare/0.70.5...0.70.6) (2023-03-28) + + +### Features + +* add search on docs ([#159](https://github.com/kurtosis-tech/kurtosis/issues/159)) ([f80d036](https://github.com/kurtosis-tech/kurtosis/commit/f80d0361435c99707291c0e96c0c308326343330)) +* integrate lsp with monrepo ([#223](https://github.com/kurtosis-tech/kurtosis/issues/223)) ([b5ed670](https://github.com/kurtosis-tech/kurtosis/commit/b5ed6707b1c3254cefcfa9201fb76ff1116dedce)) + + +### Bug Fixes + +* fix typo in reindex workflow ([#357](https://github.com/kurtosis-tech/kurtosis/issues/357)) ([8900ff2](https://github.com/kurtosis-tech/kurtosis/commit/8900ff230240487e40e706fccc3b8e32b1d1082f)) +* remove file paths from error message ([#256](https://github.com/kurtosis-tech/kurtosis/issues/256)) ([cb603d8](https://github.com/kurtosis-tech/kurtosis/commit/cb603d836772812d602bfb86736a8145b85162e1)) +* remove trailing errors after starlark execution ([724ac35](https://github.com/kurtosis-tech/kurtosis/commit/724ac355e8cf64a070c3d62a0f593399b5ef2dde)) +* remove trailing errors after starlark execution ([#257](https://github.com/kurtosis-tech/kurtosis/issues/257)) ([724ac35](https://github.com/kurtosis-tech/kurtosis/commit/724ac355e8cf64a070c3d62a0f593399b5ef2dde)) + +## [0.70.5](https://github.com/kurtosis-tech/kurtosis/compare/0.70.4...0.70.5) (2023-03-28) + + +### Features + +* Print the running engine version while running Kurtosis Version ([#346](https://github.com/kurtosis-tech/kurtosis/issues/346)) ([9ef03cb](https://github.com/kurtosis-tech/kurtosis/commit/9ef03cb22e26d9dce556e1d31bacf9b3b30da736)) + +## [0.70.4](https://github.com/kurtosis-tech/kurtosis/compare/0.70.3...0.70.4) (2023-03-28) + + +### Features + +* Added extra name generation items ([#342](https://github.com/kurtosis-tech/kurtosis/issues/342)) ([0ed2923](https://github.com/kurtosis-tech/kurtosis/commit/0ed2923d9a16cb68b706e25112a741a4b7384944)) +* Publish multi-arch image for `files-artifacts-expander` ([#344](https://github.com/kurtosis-tech/kurtosis/issues/344)) ([9e2b369](https://github.com/kurtosis-tech/kurtosis/commit/9e2b369206b974d06e5a7c172b6363e5c6fb1d92)) + +## [0.70.3](https://github.com/kurtosis-tech/kurtosis/compare/0.70.2...0.70.3) (2023-03-27) + + +### Features + +* Added `bug, feature and docs` flags in the `kurtosis feedback` command ([#287](https://github.com/kurtosis-tech/kurtosis/issues/287)) ([963e9dd](https://github.com/kurtosis-tech/kurtosis/commit/963e9dd055a3ceabafde11a4d942e16f300d827c)) + + +### Bug Fixes + +* check service name contains allowed characters and errors cleanly ([#315](https://github.com/kurtosis-tech/kurtosis/issues/315)) ([94af4bd](https://github.com/kurtosis-tech/kurtosis/commit/94af4bda3aac9a1ed45e6ac503407d271ba1d73f)), closes [#164](https://github.com/kurtosis-tech/kurtosis/issues/164) + +## [0.70.2](https://github.com/kurtosis-tech/kurtosis/compare/0.70.1...0.70.2) (2023-03-27) + + +### Features + +* Automatically restart engine on context switch ([#329](https://github.com/kurtosis-tech/kurtosis/issues/329)) ([b0712cc](https://github.com/kurtosis-tech/kurtosis/commit/b0712cc42fca1b4ba322bf473da57db4eab8c462)) + + +### Bug Fixes + +* Fix info CLI log for portal not running ([#330](https://github.com/kurtosis-tech/kurtosis/issues/330)) ([0fb938e](https://github.com/kurtosis-tech/kurtosis/commit/0fb938e31c29778ac122675e7706e3ad1fd0fc93)) + +## [0.70.1](https://github.com/kurtosis-tech/kurtosis/compare/0.70.0...0.70.1) (2023-03-27) + + +### Features + +* Add context `rm` command ([#275](https://github.com/kurtosis-tech/kurtosis/issues/275)) ([c20ca12](https://github.com/kurtosis-tech/kurtosis/commit/c20ca121443a78ed6b266cd18b5d69997ee69e57)) +* Add context `switch` CLI command ([#317](https://github.com/kurtosis-tech/kurtosis/issues/317)) ([ebab7eb](https://github.com/kurtosis-tech/kurtosis/commit/ebab7ebb697e4c791b47bff14a4e32aaa04268b5)) +* add kurtosis engine logs command that dumps logs for all engines in target dir ([#313](https://github.com/kurtosis-tech/kurtosis/issues/313)) ([cbb588c](https://github.com/kurtosis-tech/kurtosis/commit/cbb588c01a6d8d8baffcb41c87b49716c23b7cfc)) +* result of add service contains a `name` property ([#314](https://github.com/kurtosis-tech/kurtosis/issues/314)) ([af8ca5f](https://github.com/kurtosis-tech/kurtosis/commit/af8ca5f1d7ec9564baf171ea3478b71e3d9f113b)) +* Tunnel remote APIC port to local machine using Kurtosis Portal ([#295](https://github.com/kurtosis-tech/kurtosis/issues/295)) ([4c3ba69](https://github.com/kurtosis-tech/kurtosis/commit/4c3ba69062b78c5f960b4b94fa4427d2b76f6f7a)) + + +### Bug Fixes + +* add example historical version ([#150](https://github.com/kurtosis-tech/kurtosis/issues/150)) ([1548489](https://github.com/kurtosis-tech/kurtosis/commit/1548489b87aa927051b4cd01190b92be48e0714d)) +* be clear about the engine that is being started ([#282](https://github.com/kurtosis-tech/kurtosis/issues/282)) ([5bc1b79](https://github.com/kurtosis-tech/kurtosis/commit/5bc1b79e94a5688dc908bd413a7f410e8aaf2346)) +* Fix starlark value reference bug ([#322](https://github.com/kurtosis-tech/kurtosis/issues/322)) ([63f6626](https://github.com/kurtosis-tech/kurtosis/commit/63f6626be54b71a9fc09e02ae07207c9a9309409)) +* name all args for add_services instruction in quickstart ([#316](https://github.com/kurtosis-tech/kurtosis/issues/316)) ([d413826](https://github.com/kurtosis-tech/kurtosis/commit/d41382635d3ad0c51dec6f937c2c26f105fcfe13)) +* reformat build prereqs in readme ([#290](https://github.com/kurtosis-tech/kurtosis/issues/290)) ([c286151](https://github.com/kurtosis-tech/kurtosis/commit/c28615144a40cfb369e5fb35d9722ecf912fedce)) + +## [0.70.0](https://github.com/kurtosis-tech/kurtosis/compare/0.69.2...0.70.0) (2023-03-22) + + +### ⚠ BREAKING CHANGES + +* This is a breaking change where we are removing the ExecRecipe.service_name, GetHttpRequestRecipe.service_name, and PostHttpRequestRecipe.service_name fields, we suggest users pass this value as an argument in the exec, request and wait instructions where this type is currently used. We are also deprecating the previous exec, request, and wait instructions signature that haven't the service_name field, users must add this field on these instructions call. Another change is that now the service_name field on the exec, request, and wait instructions is mandatory ([#301](https://github.com/kurtosis-tech/kurtosis/issues/301)) + +### Features + +* Kurtosis backend can now connect to a remote Docker backend ([#285](https://github.com/kurtosis-tech/kurtosis/issues/285)) ([98b04c8](https://github.com/kurtosis-tech/kurtosis/commit/98b04c8c98e92c0c7e2661ae1020cee1a1cf1e4b)) +* This is a breaking change where we are removing the ExecRecipe.service_name, GetHttpRequestRecipe.service_name, and PostHttpRequestRecipe.service_name fields, we suggest users pass this value as an argument in the exec, request and wait instructions where this type is currently used. We are also deprecating the previous exec, request, and wait instructions signature that haven't the service_name field, users must add this field on these instructions call. Another change is that now the service_name field on the exec, request, and wait instructions is mandatory ([#301](https://github.com/kurtosis-tech/kurtosis/issues/301)) ([eb7e88f](https://github.com/kurtosis-tech/kurtosis/commit/eb7e88f3309f6d98e8ddb4ff8aad6baa991ea450)) + +## [0.69.2](https://github.com/kurtosis-tech/kurtosis/compare/0.69.1...0.69.2) (2023-03-22) + + +### Features + +* Add context `add` command ([#278](https://github.com/kurtosis-tech/kurtosis/issues/278)) ([bd56cae](https://github.com/kurtosis-tech/kurtosis/commit/bd56cae2c7d29dff4c6011ed80521eddfd39277d)) +* build script check for go and node versions ([#240](https://github.com/kurtosis-tech/kurtosis/issues/240)) ([4749dbe](https://github.com/kurtosis-tech/kurtosis/commit/4749dbe62030eb17bebd02f81b1a0b822f7e843d)) + +## [0.69.1](https://github.com/kurtosis-tech/kurtosis/compare/0.69.0...0.69.1) (2023-03-22) + + +### Features + +* Add `context` root command and simple `ls` subcommand ([#241](https://github.com/kurtosis-tech/kurtosis/issues/241)) ([4097c25](https://github.com/kurtosis-tech/kurtosis/commit/4097c25ad57af61f16044b1193df28b5b94acc97)) + +## [0.69.0](https://github.com/kurtosis-tech/kurtosis/compare/0.68.13...0.69.0) (2023-03-21) + + +### ⚠ BREAKING CHANGES + +* Add acceptable code for request and exec ([#212](https://github.com/kurtosis-tech/kurtosis/issues/212)) +* The --enclave-identifier, --enclave-identifiers and --service-identifier flags have been renamed to , --enclave, --enclaves and --service respectively. Users will have to change any scripts or CI configurations that depend on those flags. +* Reduce wait default timeout from 15 minutes to 10 seconds ([#211](https://github.com/kurtosis-tech/kurtosis/issues/211)) + +### Features + +* Add acceptable code for request and exec ([#212](https://github.com/kurtosis-tech/kurtosis/issues/212)) ([9b00ac2](https://github.com/kurtosis-tech/kurtosis/commit/9b00ac2674ce4d602d1eafb4e00e789709917fd5)), closes [#201](https://github.com/kurtosis-tech/kurtosis/issues/201) [#188](https://github.com/kurtosis-tech/kurtosis/issues/188) +* Add library to manage context configurations ([#196](https://github.com/kurtosis-tech/kurtosis/issues/196)) ([c27038a](https://github.com/kurtosis-tech/kurtosis/commit/c27038a41ebb94940881139f990465fffdc0c8d1)) +* added a command that allows users to open the Kurtosis Twitter page ([#265](https://github.com/kurtosis-tech/kurtosis/issues/265)) ([c8bcc91](https://github.com/kurtosis-tech/kurtosis/commit/c8bcc91b8f4ff389df216e7f446be10d9100c78c)) +* PostHttpRequestRecipe accepts empty body ([#214](https://github.com/kurtosis-tech/kurtosis/issues/214)) ([b7991dc](https://github.com/kurtosis-tech/kurtosis/commit/b7991dc32c31fcac5307d10288bc3908a1b9fc40)) +* print files artifacts registered in an enclave during enclave inspect ([#228](https://github.com/kurtosis-tech/kurtosis/issues/228)) ([ef167d6](https://github.com/kurtosis-tech/kurtosis/commit/ef167d692ebac40d60819987d2f11c47fa4658dc)) +* Reduce wait default timeout from 15 minutes to 10 seconds ([#211](https://github.com/kurtosis-tech/kurtosis/issues/211)) ([4429284](https://github.com/kurtosis-tech/kurtosis/commit/4429284e35eea6757b22a79a833297ec224c5374)) +* rename enclave and service identifier flags ([#264](https://github.com/kurtosis-tech/kurtosis/issues/264)) ([436a44a](https://github.com/kurtosis-tech/kurtosis/commit/436a44a4e4bfa22d9fe5468859f336ecd696c73a)) +* update our bug report template ([c84058b](https://github.com/kurtosis-tech/kurtosis/commit/c84058b3e0240893534b150a21cbeb5fb807bfa1)) +* update our bug report template ([#237](https://github.com/kurtosis-tech/kurtosis/issues/237)) ([c84058b](https://github.com/kurtosis-tech/kurtosis/commit/c84058b3e0240893534b150a21cbeb5fb807bfa1)) + + +### Bug Fixes + +* address typo in our calendly banner link ([#276](https://github.com/kurtosis-tech/kurtosis/issues/276)) ([e1029c3](https://github.com/kurtosis-tech/kurtosis/commit/e1029c3fc41b37468395b16158ef3d0b6cf73082)) +* clarify actions for is user-facing changes in PR template ([#279](https://github.com/kurtosis-tech/kurtosis/issues/279)) ([969c3b8](https://github.com/kurtosis-tech/kurtosis/commit/969c3b870bc837b0ee0d6f6e0c1d800cec47419f)) +* deprecate --id flag in enclave add ([#247](https://github.com/kurtosis-tech/kurtosis/issues/247)) ([974ff18](https://github.com/kurtosis-tech/kurtosis/commit/974ff186478499806156a08772ec9bc997665b31)) +* Lock default context in contexts config ([#277](https://github.com/kurtosis-tech/kurtosis/issues/277)) ([8da3b94](https://github.com/kurtosis-tech/kurtosis/commit/8da3b94405e6d5e5f1fe659b137287e97ceb061d)) +* Update PR title workflow for merge queue ([#267](https://github.com/kurtosis-tech/kurtosis/issues/267)) ([00ccfec](https://github.com/kurtosis-tech/kurtosis/commit/00ccfecf5d26ee440010c4a6ffd32f7dd7b15d8b)) +* warn if engine version is greater than cli and error if cli > engine ([#243](https://github.com/kurtosis-tech/kurtosis/issues/243)) ([03352e1](https://github.com/kurtosis-tech/kurtosis/commit/03352e128c6521b32e48f4036cbfe4ba803fbf84)) + +## [0.68.13](https://github.com/kurtosis-tech/kurtosis/compare/0.68.12...0.68.13) (2023-03-16) + + +### Features + +* made the content-type field optional in PostHttpRequestRecipe ([#222](https://github.com/kurtosis-tech/kurtosis/issues/222)) ([d551398](https://github.com/kurtosis-tech/kurtosis/commit/d551398112aded68dd348c661fb14512080a9bdb)) + + +### Bug Fixes + +* add trailing commas to Starlark code ([#218](https://github.com/kurtosis-tech/kurtosis/issues/218)) ([1bd050c](https://github.com/kurtosis-tech/kurtosis/commit/1bd050c8de01fd24bae5ffaf786aa87b86bdf134)) +* collapse current behavior into background+motivation ([#216](https://github.com/kurtosis-tech/kurtosis/issues/216)) ([853aa5d](https://github.com/kurtosis-tech/kurtosis/commit/853aa5d9ee79b7f540897f2ca0ac80f5c31740ec)) +* print the upgrade CLI warning at most hourly ([#224](https://github.com/kurtosis-tech/kurtosis/issues/224)) ([f40ee90](https://github.com/kurtosis-tech/kurtosis/commit/f40ee90c4d1008a932daa902a264acf3e4b48510)) +* refer to the new repo name in remote subpackage tests ([#225](https://github.com/kurtosis-tech/kurtosis/issues/225)) ([cd81f2e](https://github.com/kurtosis-tech/kurtosis/commit/cd81f2ef8d721e94dd0b0c668d9ddaf64b03677d)) + +## [0.68.12](https://github.com/kurtosis-tech/kurtosis/compare/0.68.11...0.68.12) (2023-03-15) + + +### Bug Fixes + +* wait instruction hanging forever when `service_name` field is not passed ([#197](https://github.com/kurtosis-tech/kurtosis/issues/197)) ([826f072](https://github.com/kurtosis-tech/kurtosis/commit/826f0727a43ca1acc05aaded41eed307b04c7d96)) + +## [0.68.11](https://github.com/kurtosis-tech/kurtosis/compare/0.68.10...0.68.11) (2023-03-15) + + +### Features + +* colorize RUNNING|STOPPED statuses for Enclaves And Containers ([#178](https://github.com/kurtosis-tech/kurtosis/issues/178)) ([8254c7f](https://github.com/kurtosis-tech/kurtosis/commit/8254c7fbf35e38840c1ff5182017f19184eccae5)) + + +### Bug Fixes + +* remove api container stuff & colorize keys ([#195](https://github.com/kurtosis-tech/kurtosis/issues/195)) ([9ccb910](https://github.com/kurtosis-tech/kurtosis/commit/9ccb9102736eda2e8cb6645796cb9bfc73209ea1)) + +## [0.68.10](https://github.com/kurtosis-tech/kurtosis/compare/0.68.9...0.68.10) (2023-03-15) + + +### Bug Fixes + +* Tag docker images correctly after Kudet removal ([#206](https://github.com/kurtosis-tech/kurtosis/issues/206)) ([2e594a4](https://github.com/kurtosis-tech/kurtosis/commit/2e594a444a2eef5b058402edf675b7526a0ec675)) + +## [0.68.9](https://github.com/kurtosis-tech/kurtosis/compare/0.68.8...0.68.9) (2023-03-15) + + +### Features + +* Add a new pull request template ([#117](https://github.com/kurtosis-tech/kurtosis/issues/117)) ([45b2067](https://github.com/kurtosis-tech/kurtosis/commit/45b2067302f9fb38c2dda43dedbdbbcc7878fea6)) +* show enclave inspect immediately after run ([#170](https://github.com/kurtosis-tech/kurtosis/issues/170)) ([5790131](https://github.com/kurtosis-tech/kurtosis/commit/57901311eefdbe877e97deef4ee3e5ba1bd4c75a)) + + +### Bug Fixes + +* Add back fetch depth to change version GH action ([f5f32a2](https://github.com/kurtosis-tech/kurtosis/commit/f5f32a294fdf365cde2e998b03e37ab1a1b42d14)) +* Add back fetch depth to change version GH action ([#204](https://github.com/kurtosis-tech/kurtosis/issues/204)) ([f5f32a2](https://github.com/kurtosis-tech/kurtosis/commit/f5f32a294fdf365cde2e998b03e37ab1a1b42d14)) +* remove & service uuid from autocomplete ([#182](https://github.com/kurtosis-tech/kurtosis/issues/182)) ([3be2070](https://github.com/kurtosis-tech/kurtosis/commit/3be207091fcb99161a7e8b8712d885a3c1298954)) +* use with-subnetworks ([#163](https://github.com/kurtosis-tech/kurtosis/issues/163)) ([db6dd41](https://github.com/kurtosis-tech/kurtosis/commit/db6dd41e7415d30d0811516525395010bb02c6d5)) + +## [0.68.8](https://github.com/kurtosis-tech/kurtosis/compare/0.68.7...0.68.8) (2023-03-14) + + +### Bug Fixes + +* bump historical cli install down the sidebar ([cba11eb](https://github.com/kurtosis-tech/kurtosis/commit/cba11eb3fe5545166b4979aeb63e2c26dd3c375b)) +* bump historical cli install down the sidebar ([#152](https://github.com/kurtosis-tech/kurtosis/issues/152)) ([cba11eb](https://github.com/kurtosis-tech/kurtosis/commit/cba11eb3fe5545166b4979aeb63e2c26dd3c375b)) +* print enclave names even after restart during clean ([#156](https://github.com/kurtosis-tech/kurtosis/issues/156)) ([43ab71e](https://github.com/kurtosis-tech/kurtosis/commit/43ab71e3305f3c434f6d5718e4e2d2b664993ae2)) + +## [0.68.7](https://github.com/kurtosis-tech/kurtosis/compare/0.68.6...0.68.7) (2023-03-13) + + +### Bug Fixes + +* added instruction position while executing starlark package ([bc70e4e](https://github.com/kurtosis-tech/kurtosis/commit/bc70e4e1b5ad743edf9dcaa7b0feb0975e8f7eb0)) +* added instruction position while executing starlark package ([#143](https://github.com/kurtosis-tech/kurtosis/issues/143)) ([bc70e4e](https://github.com/kurtosis-tech/kurtosis/commit/bc70e4e1b5ad743edf9dcaa7b0feb0975e8f7eb0)) +* fix changelog for versioned docs going forward ([#142](https://github.com/kurtosis-tech/kurtosis/issues/142)) ([2fc3e72](https://github.com/kurtosis-tech/kurtosis/commit/2fc3e72248bbbbb1780ecf32db95a6c9fbe08972)) +* gramatical fix in analytics tracking logging ([#138](https://github.com/kurtosis-tech/kurtosis/issues/138)) ([23212a3](https://github.com/kurtosis-tech/kurtosis/commit/23212a3188445e3f358eef0e3ac388752eb9a0c7)) +* sort services by name ([#139](https://github.com/kurtosis-tech/kurtosis/issues/139)) ([d60ef67](https://github.com/kurtosis-tech/kurtosis/commit/d60ef67e0fa2e456d11b0a3925dd731a969928d6)) + +## [0.68.6](https://github.com/kurtosis-tech/kurtosis/compare/0.68.5...0.68.6) (2023-03-09) + + +### Features + +* Added `kurtosis feedback` CLI command ([#28](https://github.com/kurtosis-tech/kurtosis/issues/28)) ([55210ec](https://github.com/kurtosis-tech/kurtosis/commit/55210ec5660f6c642eda4baa422cf766fc584be5)) +* publish versioned brew formula ([#130](https://github.com/kurtosis-tech/kurtosis/issues/130)) ([a7d695d](https://github.com/kurtosis-tech/kurtosis/commit/a7d695d3fc58d7c4c3c3fd218bf9af98a3bc0086)) + +## [0.68.5](https://github.com/kurtosis-tech/kurtosis/compare/0.68.4...0.68.5) (2023-03-09) + + +### Bug Fixes + +* Use version.txt for kurtosis_version instead of Git tags ([#126](https://github.com/kurtosis-tech/kurtosis/issues/126)) ([f5bfe9e](https://github.com/kurtosis-tech/kurtosis/commit/f5bfe9e5795305c172a6fd02115825b2ea0b638a)) + +## [0.68.4](https://github.com/kurtosis-tech/kurtosis/compare/0.68.3...0.68.4) (2023-03-09) + + +### Bug Fixes + +* Pass correct latest tag to GoReleaser CLI build ([#122](https://github.com/kurtosis-tech/kurtosis/issues/122)) ([ec10c54](https://github.com/kurtosis-tech/kurtosis/commit/ec10c542d2ef97dd4c3ca0d542fa5af23fc44ca2)) + +## [0.68.3](https://github.com/kurtosis-tech/kurtosis/compare/0.68.2...0.68.3) (2023-03-08) + + +### Features + +* Use semver versioning for Golang API package ([#119](https://github.com/kurtosis-tech/kurtosis/issues/119)) ([1d4ff7f](https://github.com/kurtosis-tech/kurtosis/commit/1d4ff7fea55bcf25538b955275d776ff0b2f3678)) + + +### Bug Fixes + +* remove mentions about github discussions ([#95](https://github.com/kurtosis-tech/kurtosis/issues/95)) ([2387fa2](https://github.com/kurtosis-tech/kurtosis/commit/2387fa230bc5a6d240755acbbb9b5cbcc5489ea0)) + +## [0.68.2](https://github.com/kurtosis-tech/kurtosis/compare/0.68.1...0.68.2) (2023-03-08) + + +### Bug Fixes + +* fix push_cli_artifacts ci job ([#118](https://github.com/kurtosis-tech/kurtosis/issues/118)) ([b905870](https://github.com/kurtosis-tech/kurtosis/commit/b90587057b200e7f54d1ef5a7e815a1d94a7cf4c)) + +## [0.68.1](https://github.com/kurtosis-tech/kurtosis/compare/0.68.0...0.68.1) (2023-03-08) + + +### Features + +* docs are versioned ([#106](https://github.com/kurtosis-tech/kurtosis/issues/106)) ([7cd6a4e](https://github.com/kurtosis-tech/kurtosis/commit/7cd6a4e391d7b261cdb2d94d3d9dac2be7f3490b)) + +## [0.68.0](https://github.com/kurtosis-tech/kurtosis/compare/0.67.4...0.68.0) (2023-03-07) + + +### ⚠ BREAKING CHANGES + +* Migrate Kurtosis Print instruction to Starlark framework. This restrict the use of `print` to a single argument only. ([#80](https://github.com/kurtosis-tech/kurtosis/issues/80)) (#87) + +### Features + +* enclave clean has both name and uuid ([#101](https://github.com/kurtosis-tech/kurtosis/issues/101)) ([69114ab](https://github.com/kurtosis-tech/kurtosis/commit/69114ab455715092060d51d854f18241f0fb4060)) +* persist partition connection overrides to disk ([#98](https://github.com/kurtosis-tech/kurtosis/issues/98)) ([4af3b9f](https://github.com/kurtosis-tech/kurtosis/commit/4af3b9f31daf4962a1e4242a001d2d4bcc84f8d0)) + + +### Code Refactoring + +* Migrate Kurtosis Print instruction to Starlark framework. This restrict the use of `print` to a single argument only. ([#80](https://github.com/kurtosis-tech/kurtosis/issues/80)) ([#87](https://github.com/kurtosis-tech/kurtosis/issues/87)) ([868da1b](https://github.com/kurtosis-tech/kurtosis/commit/868da1b871f5b2610dfcc97618c13861a180cc80)) + +## [0.67.4](https://github.com/kurtosis-tech/kurtosis/compare/0.67.3...0.67.4) (2023-03-04) + + +### Features + +* added new `service_name` parameter for the `exec`, `request` and `wait` instructions. NOTE: the previous methods' signature will be maintained during a deprecation period, we suggest users update the methods' calls to this new signature. ([#66](https://github.com/kurtosis-tech/kurtosis/issues/66)) ([1b47ee3](https://github.com/kurtosis-tech/kurtosis/commit/1b47ee3bb3fd56711995596fb9f68c5a195291fb)) +* added the `id` flag in the `analytics` CLI command which allow users to get the `analytics ID` in an easy way ([#81](https://github.com/kurtosis-tech/kurtosis/issues/81)) ([766c094](https://github.com/kurtosis-tech/kurtosis/commit/766c0944a983a0f26e2f7bb3f24ce20f3db28d4b)) +* integrate nature theme based name to cli (render template and store service) for file artifacts ([#82](https://github.com/kurtosis-tech/kurtosis/issues/82)) ([aea5bef](https://github.com/kurtosis-tech/kurtosis/commit/aea5bef1fdbd16f88bc4021e243d60f24491b616)) +* integrate nature theme named to render_template and store_service ([aea5bef](https://github.com/kurtosis-tech/kurtosis/commit/aea5bef1fdbd16f88bc4021e243d60f24491b616)) +* introduce nature themed name for enclaves ([#59](https://github.com/kurtosis-tech/kurtosis/issues/59)) ([78e363f](https://github.com/kurtosis-tech/kurtosis/commit/78e363f554494891b28b4e277e3b04473a66af7b)) +* persist service partitions ([#84](https://github.com/kurtosis-tech/kurtosis/issues/84)) ([d46d92a](https://github.com/kurtosis-tech/kurtosis/commit/d46d92a1f0a1db3ba2099e31570983faa0d93874)) + + +### Bug Fixes + +* handle multiline errors that might happen with kurtosis clean ([#69](https://github.com/kurtosis-tech/kurtosis/issues/69)) ([f7400be](https://github.com/kurtosis-tech/kurtosis/commit/f7400beac0c7a7f2ec04486064d7bf0c63758cf5)) + +## [0.67.3](https://github.com/kurtosis-tech/kurtosis/compare/0.67.2...0.67.3) (2023-02-28) + + +### Features + +* Add new FR, docs, and Bug Report issues templates ([#52](https://github.com/kurtosis-tech/kurtosis/issues/52)) ([8854585](https://github.com/kurtosis-tech/kurtosis/commit/88545857213f25716abf4030f03cdd71db531c83)) +* made the name field optional for file artifacts in starlark ([#51](https://github.com/kurtosis-tech/kurtosis/issues/51)) ([1ded385](https://github.com/kurtosis-tech/kurtosis/commit/1ded385720423f58a168b44afb94279d1d2c3951)) + + +### Bug Fixes + +* Correct minor error in "locators" reference docs ([#71](https://github.com/kurtosis-tech/kurtosis/issues/71)) ([3d68919](https://github.com/kurtosis-tech/kurtosis/commit/3d68919aafbc16e8211cd7692d1820bbe7301070)) +* stamp enclave uuid at the end of enclave objects ([#74](https://github.com/kurtosis-tech/kurtosis/issues/74)) ([4f44d03](https://github.com/kurtosis-tech/kurtosis/commit/4f44d03769c877fc36349a79a47b347d2444cf75)) + +## [0.67.2](https://github.com/kurtosis-tech/kurtosis/compare/0.67.1...0.67.2) (2023-02-27) + + +### Features + +* added boilerplate method to generate unique file artifact name ([#40](https://github.com/kurtosis-tech/kurtosis/issues/40)) ([50cd25c](https://github.com/kurtosis-tech/kurtosis/commit/50cd25cddeccbadf450e7888155b3b39f58acd4b)) +* fix the output of kurtosis enclave dump ([#62](https://github.com/kurtosis-tech/kurtosis/issues/62)) ([7ae12cf](https://github.com/kurtosis-tech/kurtosis/commit/7ae12cf51f966a64b3684f3ad439befb8bf2d7c1)) + + +### Bug Fixes + +* enforced kurtosis locator validations when running remote kurtosis package ([#41](https://github.com/kurtosis-tech/kurtosis/issues/41)) ([e9af4d9](https://github.com/kurtosis-tech/kurtosis/commit/e9af4d9701e5ecc5b53811d839563140cdc5de22)) +* preserve cli provided ordering of completions throughout shells ([#61](https://github.com/kurtosis-tech/kurtosis/issues/61)) ([f312f2c](https://github.com/kurtosis-tech/kurtosis/commit/f312f2c276b335f64c87fd8e34a7fdca5814a75c)) + +## [0.67.1](https://github.com/kurtosis-tech/kurtosis/compare/0.67.0...0.67.1) (2023-02-23) + + +### Features + +* added Kurtosis Docs command ([#34](https://github.com/kurtosis-tech/kurtosis/issues/34)) ([2502bae](https://github.com/kurtosis-tech/kurtosis/commit/2502baecdfa57dabd8e3bb0d69569c38e6f27645)) + + +### Bug Fixes + +* better errors when enclave cleaning fails ([#47](https://github.com/kurtosis-tech/kurtosis/issues/47)) ([a15fe52](https://github.com/kurtosis-tech/kurtosis/commit/a15fe5282652e406e779dfad37fa9ee8cf8ed771)) +* enforce kurtosis.yml validations in import_module and read_file; package name inside kurtosis.yml must be valid and is same as the path where kurtosis.yml exists ([#24](https://github.com/kurtosis-tech/kurtosis/issues/24)) ([95d5548](https://github.com/kurtosis-tech/kurtosis/commit/95d554808eaf07928058285016bf6f3a5aff9359)) +* fix error message on importing/reading a package instead of a module ([#33](https://github.com/kurtosis-tech/kurtosis/issues/33)) ([1f906ae](https://github.com/kurtosis-tech/kurtosis/commit/1f906ae5dc70a48b670ddda8065e12b81a9bb55c)) +* fixed link to report docs issues ([#36](https://github.com/kurtosis-tech/kurtosis/issues/36)) ([dfccf10](https://github.com/kurtosis-tech/kurtosis/commit/dfccf10c01aa5c981fb60fce97725a427fc4d1be)) + +## [0.67.0](https://github.com/kurtosis-tech/kurtosis/compare/0.66.11...0.67.0) (2023-02-21) + + +### ⚠ BREAKING CHANGES + +* This is a breaking change where we are deprecating PacketDelay to introduce latency in favour of PacketDelayDistribution. Instead of using packet delay, use UniformPacketDelayDistribution for constant delays or NormalPacketDelayDistribution for normally distributed latencies + +## [0.66.11](https://github.com/kurtosis-tech/kurtosis/compare/0.66.10...0.66.11) (2023-02-21) + + +### Features + +* track enclave size after run has finished ([#15](https://github.com/kurtosis-tech/kurtosis/issues/15)) ([80f35c8](https://github.com/kurtosis-tech/kurtosis/commit/80f35c80797b00fd66b4d216b9807b63cf2739b7)) + + +### Bug Fixes + +* import_module and read_file should load files from kurtosis packages (kurtosis.yml must be present in the path). enforce that only kurtosis packages (directories containing kurtosis.yml) can be run. ([#16](https://github.com/kurtosis-tech/kurtosis/issues/16)) ([84f1042](https://github.com/kurtosis-tech/kurtosis/commit/84f1042aef2d79b388bb5eaf808df520a3e76462)) + +## [0.66.10](https://github.com/kurtosis-tech/kurtosis/compare/0.66.9...0.66.10) (2023-02-16) + + +### Features + +* made metrics opt in by default ([#5](https://github.com/kurtosis-tech/kurtosis/issues/5)) ([cd076fd](https://github.com/kurtosis-tech/kurtosis/commit/cd076fd515a05e594f338e693405d614718e59f4)) +* update metrics lib to track os, arch & backend type ([#11](https://github.com/kurtosis-tech/kurtosis/issues/11)) ([15cf9bb](https://github.com/kurtosis-tech/kurtosis/commit/15cf9bbec3b37a6235901d01e207be36366e8614)) + +## [0.66.9](https://github.com/kurtosis-tech/kurtosis/compare/0.66.8...0.66.9) (2023-02-15) + + +### Bug Fixes + +* Fix release process ([#3](https://github.com/kurtosis-tech/kurtosis/issues/3)) ([8a618d9](https://github.com/kurtosis-tech/kurtosis/commit/8a618d94bebe0553f744ab90b6e4c8fe2f8f7fdb)) + +## 0.66.8 (2023-02-15) + + +### Features + +* Initial implementation ([#1](https://github.com/kurtosis-tech/kurtosis/issues/1)) ([8a3fd81](https://github.com/kurtosis-tech/kurtosis/commit/8a3fd8123388de117f4a8c84622024923d410fc3)) diff --git a/docs/versioned_docs/version-0.70.6/explanations/architecture.md b/docs/versioned_docs/version-0.70.6/explanations/architecture.md new file mode 100644 index 0000000000..09f1b108e3 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/architecture.md @@ -0,0 +1,68 @@ +--- +title: Kurtosis Architecture +sidebar_label: Architecture +sidebar_position: 2 +--- + +![Kurtosis Architecture](@site/static/img/explanations/kurtosis-architecture.png) + +Kurtosis At A Macro Level +------------------------- +At a macro level, Kurtosis is an engine (a set of Kurtosis servers) deployed on top of a container orchestrator (e.g. Docker, Kubernetes). All interaction with Kurtosis is done via the Kurtosis APIs. After the Kurtosis engine receives a request, it usually modifies some state inside the container orchestrator. Kurtosis therefore serves as an abstraction layer atop the container orchestrator, so that code written for Kurtosis is orchestrator-agnostic. + +To understand what the Kurtosis engine does, we'll need to understand environments. Kurtosis' philosophy is that [the distributed nature of modern software means that modern software development now happens at the environment level][what-is-kurtosis]. To respond to this need, environments are a first-class concept in Kurtosis: easy to create, easy to inspect, easy to modify, and easy to destroy. + +Therefore, the job of the Kurtosis engine is to receive requests from the client and translate them to instructions for the underlying container orchestration engine. These requests can be simple commands that map 1:1 to instructions to the underlying container orchestrator (e.g. "add service X to environment Y"), or they can be Kurtosis-only commands that require complex interaction with the container orchestrator (e.g. "divide environment X in two with a simulated network partition"). + +Enclaves +-------- +Kurtosis implements "environments as a first-class" concept using **enclaves**. An enclave can be thought of an "environment container" - an isolated place for a user to run an environment that is easy to create, manage, and destroy. Each enclave is separate from the other enclaves: no network communication can happen between them. Enclaves are also cheap: each Kurtosis engine can manage arbitrary numbers of enclaves, limited only by the underlying hardware. + +Example: Some enclaves running in a Kurtosis engine, as displayed by [the Kurtosis CLI][installation]: + +``` +EnclaveUUID Name Status Creation Time +a525cee593af4b45aa15785e87d3b7c9 local RUNNING Thu, 24 Nov 2022 14:11:27 UTC +edf36be917504e449a1648cf8d6c78a4 test RUNNING Thu, 24 Nov 2022 14:11:34 UTC +``` + +Services +-------- +Enclaves contain distributed applications, and distributed applications have services. A service in Kurtosis is a container that exposes ports, and services may depend on other services (e.g. an API server depending on a database). Each enclave can have an arbitrary numbers of services, limited only by the underlying hardware. + +Example: A pair of Nginx services running inside an enclave called `test`, as reported by the Kurtosis CLI: + +``` +Enclave UUID: 2e42f9fd7b854eabb04f71a15bd1b55f +Enclave Name: test +Enclave Status: RUNNING +Creation Time: Thu, 24 Nov 2022 11:11:34 -03 +API Container Status: RUNNING +API Container Host GRPC Port: 127.0.0.1:60768 +API Container Host GRPC Proxy Port: 127.0.0.1:60769 + +========================================== User Services ========================================== +GUID ID Ports Status +nginx-1669299161 nginx http: 80/tcp -> 127.0.0.1:60785 RUNNING +nginx2-1669299176 nginx2 http: 80/tcp -> 127.0.0.1:60794 RUNNING +``` + +SDKs +---- +All interaction with Kurtosis happens via API requests to the Kurtosis engine. To assist with calling the API, [we provide SDKs in various languages](https://github.com/kurtosis-tech/kurtosis-sdk). Anything the Kurtosis engine is capable of doing will be available via the API and, therefore, via the SDKs. + +For day-to-day operation, we also provide [a CLI ][installation] (usage guide [here][cli-usage]). This is a Go CLI that uses the Go SDK underneath. + +Kurtosis Instruction Language +----------------------------- +Distributed system definitions are complex. To allow users to express their system in the simplest way possible while still fulfilling the required [properties of a reusable environment definition][reusable-environment-definitions], the Kurtosis engine provides users with the ability [to define and manipulate enclaves using Google's Starlark configuration language][starlark-explanation]. The Kurtosis engine contains a Starlark interpreter, and users can [send Starlark instructions][starlark-instructions] via the Kurtosis SDK to tell the engine what to do with an enclave. This allows users to define their environments as code. + +For a reference list of the available Starlark instructions, [see here][starlark-instructions]. + + +[installation]: ../guides/installing-the-cli.md +[cli-usage]: ../reference/cli/cli.md +[reusable-environment-definitions]: ./reusable-environment-definitions.md +[what-is-kurtosis]: ./what-is-kurtosis.md +[starlark-explanation]: ./starlark.md +[starlark-instructions]: ../reference/starlark-instructions.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/explanations/how-do-kurtosis-imports-work.md b/docs/versioned_docs/version-0.70.6/explanations/how-do-kurtosis-imports-work.md new file mode 100644 index 0000000000..78e1fad923 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/how-do-kurtosis-imports-work.md @@ -0,0 +1,143 @@ +--- +title: How Do Kurtosis Imports Work? +sidebar_label: How Do Kurtosis Imports Work? +--- + +### Background +Kurtosis allows a [Starlark script][starlark-explanation] to use content from other files. This might be importing code from another Starlark file (via the `import_module` [instruction][starlark-instructions-reference]), or using contents of a static file (via the `read_file` [instruction][starlark-instructions-reference]). + +In both cases, the Kurtosis engine needs to know where to find the external file. There are two cases where external files might live: + +1. Locally: the external file lives on the same filesystem as the Starlark script that is trying to use it. +1. Remotely: the external file lives somewhere on the internet. + +Therefore, Kurtosis needs to handle both of these. + +:::info +This external files problem is not unique to Kurtosis. Every programming language faces the same challenge, and each programming language solves it differently. + +
+Click to see examples + +- In Javascript, local files are referenced via relative imports: + + ```javascript + import something from ../../someDirectory/someFile + ``` + + and remote files are downloaded as modules using `npm` or `yarn` and stored in the `node_modules` directory. The remote files will then be available via: + + ```javascript + import some-package + ``` + +- In Python, local files are handled via the [relative import syntax](https://docs.python.org/3/reference/import.html#package-relative-imports): + + ```python + from .moduleY import spam + from ..moduleA import foo + ``` + + and remote files are downloaded as packages using `pip`, stored somewhere on your machine, and made available via the `PYTHONPATH` variable. The package will then be available via regular import syntax: + + ```python + import some_package + ``` + +- In Java, the difference between local and remote files is less distinct because all files are packaged in JARs. Classes are imported using Java's import syntax: + + ```java + import com.docker.clients.Client; + ``` + + and the Java classpath is searched for each import to see if any JAR contains a matching file. It is the responsibility of the user to build the correct classpath, and various tools and dependency managers help developers download JARs and construct the classpath correctly. + +
+::: + +### Kurtosis Packages +Remote file imports in any language are always handled through a packaging system. This is because any language that allows remote external files must have a solution for identifying the remote files, downloading them locally, and making them available on the import path (`PYTHONPATH`, `node_modules`, classpath, etc.). Furthermore, authors must be able to bundle files together into a package, publish them, and share them. Thus, For Kurtosis to allow Starlark scripts to depend on remote external files, we needed a packaging system of our own. + +Of all the languages, we have been most impressed by [Go's packaging system (which Go calls "modules")](https://go.dev/blog/using-go-modules). In Go: + +- Modules are easy to create by adding a `go.mod` manifest file to a directory ([example](https://github.com/kurtosis-tech/kurtosis-sdk/blob/main/api/golang/go.mod)) +- Dependencies are easy to declare in the `go.mod` file +- Modules are published to the world simply by pushing up to GitHub + +Kurtosis code needs to be easy to share, so we modelled our packaging system off Go's. + +In Kurtosis, a directory that has [a `kurtosis.yml` file][kurtosis-yml-reference] is the package root of a [Kurtosis package][packages-reference], and all the contents of that directory will be part of the package. Any Starlark script inside the package will have the ability to use external files (e.g. via `read_file` or `import_module`) by specifying [the locator][locators-reference] of the file. + +Each package will be named with the `name` key inside the `kurtosis.yml` file. Package names follow the format `github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml` as specified in [the `kurtosis.yml` documentation][kurtosis-yml-reference]. This package name is used to determine whether a file being imported is local (meaning "found inside the package") or remote (meaning "found from the internet"). The logic for resolving a `read_file`/`import_module` is as follows: + +- If the package name in the `kurtosis.yml` is a prefix of the [locator][locators-reference] used in `read_file`/`import_module`, then the file is assumed to be local inside the package. The package name in the locator (`github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml`) references the package root (which is the directory where the `kurtosis.yml` lives), and each subpath appended to the package name will traverse down in the repo. + +- If the package name is not a prefix of the [locator][locators-reference] used in `read_file`/`import_module`, then the file is assumed to be remote. Kurtosis will look at the `github.com/package-author/package-repo` prefix of the locator, clone the repository from GitHub, and use the file inside the package i.e a directory that contains kurtosis.yml. + +:::info +Since `kurtosis.yml` can live in any directory, users have the ability to create multiple packages per repo (sibling packages). We do not currently support a package importing a sibling package (i.e. if `foo` and `bar` packages are subdirectories of `repo`, then `bar` cannot import files from `foo`). Please let us know if you need this functionality. +::: + +Kurtosis does not allow referencing local files outside the package (i.e. in a directory above the package root with the `kurtosis.yml` file). This is to ensure that all files used in the package get pushed to GitHub when the package is published. + +### Packages in Practice +There are three ways to run Kurtosis Starlark. The first is by running a script directly: + +``` +kurtosis run some-script.star +``` + +Because only a script was specified, Kurtosis does not have the `kurtosis.yml` or package name necessary to resolve file imports. Therefore, any imports used in the script will fail. + +The second way is to run a runnable package by pointing to the package root: + +``` +# OPTION 1: Point to the directory containing the `kurtosis.yml` and `main.star` +kurtosis run /path/to/package/root # Can also be "." + +# OPTION 2: Point to a `kurtosis.yml` file directly, with a `main.star` next to it +kurtosis run /path/to/package/root/kurtosis.yml +``` + +In both cases, Kurtosis will run the `main.star` in the package root and resolve any file imports using the package name specified in the `kurtosis.yml`. All local imports (imports that have the package name as a prefix to the locator) will be resolved within the directory on your filesystem; this is very useful for local development. + +:::info +Not all packages have a `main.star` file, meaning not all packages are runnable; some packages are simply libraries intended to be imported in other packages. +::: + +The third way is to run a runnable package by its package name (can be found in the kurtosis.yml from the directory): + +``` +# if kurtosis.yml is in repository root +kurtosis run github.com/package-author/package-repo +``` + +``` +# if kurtosis.yml is in any other directory +kurtosis run github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml +``` + +Kurtosis will clone the package from GitHub, run the `main.star`, and use the `kurtosis.yml` to resolve any imports. This method always uses the version on GitHub. + +:::tip +If you want to run a non-main branch, tag or commit use the following syntax +`kurtosis run github.com/package-author/package-repo@tag-branch-commit` +::: + + +:::tip +When you're developing locally, before your package has been pushed to GitHub, the package `name` can be anything you like - e.g. `github.com/test/test`. The only thing that is important for correctly resolving local file imports is that your `read_file`/`import_module` locators also are prefixed with `github.com/test/test`. + +Once you push to GitHub, however, your package `name` will need to match the author and repo. If they don't, your package will be broken when another user depends on your package because Kurtosis will go looking for a `github.com/test/test` package that likely doesn't exist. +::: + + +[starlark-explanation]: ./starlark.md +[starlark-instructions-reference]: ../reference/starlark-instructions.md +[kurtosis-yml-reference]: ../reference/kurtosis-yml.md +[packages-reference]: ../reference/packages.md +[locators-reference]: ../reference/locators.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/explanations/metrics-philosophy.md b/docs/versioned_docs/version-0.70.6/explanations/metrics-philosophy.md new file mode 100644 index 0000000000..49e0fba708 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/metrics-philosophy.md @@ -0,0 +1,17 @@ +--- +title: Metrics Philosophy +sidebar_label: Metrics Philosophy +--- + +Kurtosis is a small startup, which means that understanding how users are using the product is vital to our success. To this end, we've built the capability for Kurtosis to send product analytics metrics. + +However, user metrics are abused heavily in today's world - data is collected without the ability to disable analytics, intentionally deanonymized, and sold to third parties. We hate it as much as we're guessing you do. + +It was therefore important to us to collect our product analytic metrics ethically. Concretely, this means that we've made our metrics: + +1. Private: we will **never** give or sell your data to third parties +1. Anonymized: your user ID is a hash, so we don't know who you are +1. Obfuscated: potentially-sensitive parameters (e.g. enclave IDs) are hashed as well +1. Opt-out: Kurtosis allows you to [easily switch off analytics](../reference/cli/analytics-disable.md), even [in CI](../guides/running-in-ci.md) + +If that sounds fair to you, we'd really appreciate you helping us get the data to make our product better. In exchange, you have our word that we'll honor the trust you've placed in us by continuing to fulfill the metrics promises above. diff --git a/docs/versioned_docs/version-0.70.6/explanations/public-and-private-ips-and-ports.md b/docs/versioned_docs/version-0.70.6/explanations/public-and-private-ips-and-ports.md new file mode 100644 index 0000000000..c07f3db2e0 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/public-and-private-ips-and-ports.md @@ -0,0 +1,44 @@ +--- +title: How Private & Public IPs & Ports Work +sidebar_label: How Private & Public IPs & Ports Work +--- + +The IP addresses and ports that come out of Kurtosis can be confusing at times. This document will explain how Kurtosis handles public and private IPs and ports. + +### Private IPs +Each Docker or Kubernetes cluster has a private IP address range, from `0.0.0.0` to `255.255.255.255`. Each container gets IP addresses from this range, and containers talk to other containers using these IP addresses. These IP addresses have nothing to do with the outside world's IP addresses, and are purely internal to the cluster. + +These IP addresses are private to Docker/Kubernetes, so you will not be able to reach them from your host machine (i.e. outside the Docker/Kubernetes cluster). For example, a container with IP address `172.0.1.3` will _not_ be reachable by `curl` from your regular command line. + +### Private Ports +Containers can listen on ports. These ports do not conflict with other containers, nor do they conflict with ports on your host machine, outside the Docker/Kubernetes cluster. For example: + +- You might be running Container A running a server listening on port `3000`, and Container B running a server listening on port `3000`. Even though the containers are using the same port, they are treated separately inside of Docker/Kubernetes and do not conflict. +- You might be running a server on your host machine on port `3000`, and a container in Docker/Kubernetes listening on port `3000`. This is also fine, because the Docker/Kubernetes ports are private to the cluster. + +These container ports are private: you will not be able to access them from your host machine. + +### Public IPs & Ports +To simplify your work, Kurtosis allows you to connect to every private port of every container. This is accomplished by binding every private port to an [ephemeral port](https://unix.stackexchange.com/questions/65475/ephemeral-port-what-is-it-and-what-does-it-do) on your host machine. These ephemeral ports are called the "public ports" of the container because they allow the container to be accessed outside the Docker/Kubernetes cluster. To view the private & public port bindings of each container in Kurtosis, run `kurtosis enclave inspect` and look for the bindings in the "Ports" column: + +``` +========================================== User Services ========================================== +GUID ID Ports Status +cl-beacon-1670597432 cl-beacon http: 4000/tcp -> 127.0.0.1:55947 RUNNING + metrics: 5054/tcp -> 127.0.0.1:55948 + tcp-discovery: 9000/tcp -> 127.0.0.1:55949 + udp-discovery: 9000/udp -> 127.0.0.1:52875 +cl-validator-1670597459 cl-validator http: 5042/tcp -> 127.0.0.1:55955 RUNNING + metrics: 5064/tcp -> 127.0.0.1:55954 +el-1670597405 el engine-rpc: 8551/tcp -> 127.0.0.1:55930 RUNNING + rpc: 8545/tcp -> 127.0.0.1:55928 + tcp-discovery: 30303/tcp -> 127.0.0.1:55927 + udp-discovery: 30303/udp -> 127.0.0.1:57433 + ws: 8546/tcp -> 127.0.0.1:55929 +forkmon-1670597469 forkmon http: 80/tcp -> 127.0.0.1:55962 RUNNING +grafana-1670597488 grafana http: 3000/tcp -> 127.0.0.1:55998 RUNNING +``` + +The IP address used to reach these containers is your localhost address, `127.0.0.1`. This is the "public IP address" of each container in the cluster. + +The combination of public IP + port _will_ allow you to connect to a container from your command line. For example, from the output above, `curl 127.0.0.1:55947` on your command line would make a request to private port `4000` on the `cl-client-0-beacon` service. diff --git a/docs/versioned_docs/version-0.70.6/explanations/reusable-environment-definitions.md b/docs/versioned_docs/version-0.70.6/explanations/reusable-environment-definitions.md new file mode 100644 index 0000000000..4bbb7d57a7 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/reusable-environment-definitions.md @@ -0,0 +1,57 @@ +--- +title: Reusable Environment Definitions +sidebar_label: Reusable Environment Definitions +--- + +Why are reusable environment definitions hard? +---------------------------------------------- +We have many tools for defining and modifying environments: Bash/Python scripts, Ansible, Docker Compose, Helm, and Terraform. Yet, none have proven successful at reuse across [the plethora of environments in today's world][what-is-kurtosis]. To see why, we'll focus on the three most common environment types: local Dev, ephemeral Test in CI, and Prod. + +Environment definitions in Dev, Test, and Prod share some common requirements: + +- They must be easy to read and write +- They must be parameterizable +- They must handle data (e.g. on-disk files, database dumps, etc.) +- They should do some amount of validation + +They also have distinct differences: + +- In Dev, environment definitions must be loose and easy to modify, are often not checked into source control, and are rarely shared due to the prototyping nature. However, developers _do_ want to leverage other public environment definitions to form their local development environments quickly (e.g. to combine public definitions for Postgres and Elasticsearch to form a Postgres+Elasticsearch local development environment). +- In Test, environment definitions should be source-controlled, but are rarely shared given how specific the environment definition is to the scenario being tested. The order in which events happen is very important, so determinism and ordering of events matter. +- In Prod, environment definitions must be source-controlled. They may be shared, but can only be modified by authorized individuals. They are nearly always declarative: idempotence is very important in Prod, along with the ability to make the minimal set of changes (e.g. add just a few new services without needing to restart the entire stack). + +Why aren't the current solutions reusable? +------------------------------------------ +With this lens, we see why none of the most common solutions can be reused across Dev, Test, and Prod: + +- Scripting can be used for Dev and Test, but instantiating just a part of the environment requires extensive parameterization. Scripting is also not declarative, and requires the author to build in idempotence. Validation and data-handling is left to the author. Finally, scripts can get very complex and require specialized knowledge to understand. +- Ansible behaves like scripting with idempotence and validation on top. It is better in the Prod usecase than scripting, but doesn't ease the Dev/Test usecase of instantiating just a part of the system. +- Docker Compose is great for Dev and even for some Test, but fails in Prod for its lack of idempotence and its requirement to bring the entire stack down and up each time. It has no validation, little parameterizability, and Docker Compose files cannot be plugged together. +- Helm is excellent for the Prod usecase for its idempotence, parameterizability, and emphasis on sharing, but Helm charts are complex and difficult to compose or decompose. Like Docker Compose, data-handling is via volumes only. The only execution mode is declarative, so Helm only fills the Test usecase when mixed with a procedural language. +- Terraform, like Helm, hits the Prod usecase very well. However, like Helm, Terraform can only be executed in declarative mode; Test usecases with Terraform therefore need a procedural langauge to sequence events. + +What does a reusable solution look like? +---------------------------------------- +Kurtosis believes that any environment definition that aims to be reusable across Dev, Test, and Prod must have six properties: + +1. **Composability:** The user should be able to combine two or more environment definitions to form a new one (e.g. Postgres + Elasticsearch). + - In Dev, Test, and Prod, this allows modularization of definitions +1. **Decomposability:** The user should be able to take an existing environment definition and strip out the parts they're not interested in to form a smaller environment definition (e.g. take the large Prod environment definition and instantiate only a small portion of it). + - In Dev, Test, and Prod, this consumers of third-party definitions can select only the sub-components of the definition that are of interest + - In Dev, developers can select just the parts of their Prod system that they're working on +1. **Safety:** The user should be able to know whether the environment definition will work before instantiating it (analogous to type-checking - e.g. verifying all the ports match up, all the IP addresses match up, all the container images are available, etc.). + - In Dev, Test, and Prod, this left-shifts classes of errors from runtime to validation time resulting in a tighter feedback loop +1. **Parameterizability:** An environment definition should be able to accept parameters (e.g. define the desired number of Elasticsearch nodes). + - In Dev, Test, and Prod, parameterizability is essential to keeping environment definitions DRY +1. **Pluggability of Data:** The data used across Dev, Test, and Prod varies so widely that the user should be able to configure which data to use. + - In Dev, Test, and Prod, this allows for a definition to be reusable even when the data isn't the same +1. **Portability:** An environment definition author should be able to share their work and be confident that it can be consumed. + - In Dev, Test, and Prod, this allows for reuse of definitions + - In Test, test cases that failed on a CI machine can be reproduced on a developer's machine + +[Kurtosis environment definitions][starlark] are designed with these six properties in mind. + + + +[starlark]: ./starlark.md +[what-is-kurtosis]: ./what-is-kurtosis.md diff --git a/docs/versioned_docs/version-0.70.6/explanations/starlark.md b/docs/versioned_docs/version-0.70.6/explanations/starlark.md new file mode 100644 index 0000000000..0833c79a52 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/starlark.md @@ -0,0 +1,63 @@ +--- +title: Starlark +sidebar_label: Starlark +--- + +What is Starlark? +----------------- +[Starlark](https://github.com/bazelbuild/starlark) is a minimal programming language, halfway between a configuration language and a general-purpose programming language. It was developed by Google to do configurations for the [Bazel build tool](https://bazel.build/rules/language), and has since [been adopted by Facebook for the Buck build system as well](https://github.com/facebookexperimental/starlark-rust). Starlark's syntax is a minimal subset of of Python, with a focus on readability. [This page][starlark-differences-with-python] lists the differences between Starlark and Python. + +How is Starlark used with Kurtosis? +----------------------------------- +Kurtosis uses Starlark as the language for users to define and transform environments ([enclaves][enclaves]). Users submit Starlark scripts to the Kurtosis engine, the Starlark is interpreted, and the instructions in the script are executed. + +Starlark is also the way Kurtosis environment definitions are shared. If a user shares a Starlark snippet or file, the user is sharing the environment definition itself. + +Why did Kurtosis choose Starlark for its environment definitions? +----------------------------------------------------------------- +Kurtosis [aims to provide a single distributed application development tool across Dev, Test, and Prod][what-is-kurtosis]. We believe that [any reusable environment definition must have certain characteristics][reusable-environment-definitions]. With these properties in mind, we searched for tools that could fulfill our needs. + +We first looked at pure configuration languages like YAML, Jsonnet, Dhall, and CUE. To use them, we'd need to write our own DSL (and accompanying parser) on top of the language to do what we needed. We knew that the parameterizability requirement meant users would need conditional/looping logic, but we were unhappy with how we'd have to invent conditionals, loops, and parameters from scratch. The conditionals and parameters in the CircleCI YAML DSL seem to be a cautionary tale of starting with a declarative language and adding logic constructs later, and [others](https://github.com/tektoncd/experimental/issues/185#issuecomment-535338943) seemed [to agree](https://solutionspace.blog/2021/12/04/every-simple-language-will-eventually-end-up-turing-complete/): when dealing with configuration, start with a Turing-complete language because you will eventually need it. + +We next looked at letting users declare environment definitions in their preferred general-purpose language, like Pulumi. This would require a large effort from our side to support many different SDKs, but we would do it if it was the right choice. However, we ultimately rejected this option because we realized that Kurtosis environment definitions in general-purpose programming languages: + +1. Are _too_ powerful: we'd need to run user code to construct an environment, and running arbitrary user code is a security risk in one general-purpose language let alone in various. +1. Aren't friendly for the environment definition author: to make an environment definition portable, the author would have to bundle their definition inside a container. Containerization makes development more painful (the user must know about Dockerfiles, their best practices, and how to build them locally), and requires a CI job to publish the container images up to Dockerhub. +1. Aren't friendly for the environment definition consumer: a developer investigating a third-party environment definition could easily be faced with a language they're not familiar with. Worse, general-purpose languages have many patterns for accomplishing the same task, so the consumer would need to understand the class/object/function architecture. + +When we discovered Starlark, the fit was obvious. Starlark: + +- Is syntactically valid Python, which most developers are familiar with and which has much tooling +- [Intentionally removes many Python features][starlark-differences-with-python], to make Starlark easier to read and understand +- Has [several properties that are very useful for Kurtosis](https://github.com/bazelbuild/starlark#design-principles), thanks to Starlark's origin as a build system definition language +- [Has been around in Google since at least 2017](https://blog.bazel.build/2017/03/21/design-of-skylark.html), meaning it's well-vetted +- Is used for both Google and Facebook's build system, meaning it isn't going away any time soon +- [Is used by several other companies beyond Google and Facebook](https://github.com/bazelbuild/starlark/blob/master/users.md#users) + +How is Starlark implemented at Kurtosis? +---------------------------------------- +Starlark itself is very basic; Google designed it to be extended to fulfill a given usecase (e.g. the Bazel build language is actually an extension built on top of Starlark). We extended basic Starlark with several features so that it could [fulfill the properties of reusable environment definitions][reusable-environment-definitions]: + +- A [list of Kurtosis-specific functions][starlark-instructions-reference] for working with an environment +- The [ability to accept parameters][run-args-reference] +- Dependencies, so Kurtosis scripts can [import other scripts][locators-reference] +- A [GitHub-based packaging system][packages-reference], so environment definitions can be shared with each other + +Additionally, we built a [multi-phase engine][multi-phase-runs-reference] around the Starlark interpreter, to provide [users with benefits not normally available in a scripting language][multi-phase-runs-explanation]. + +The [quickstart][quickstart] section for Starlark should get you up and running quickly. + + +[what-is-kurtosis]: ./what-is-kurtosis.md +[enclaves]: ./architecture.md#enclaves +[reusable-environment-definitions]: ./reusable-environment-definitions.md +[starlark-differences-with-python]: https://bazel.build/rules/language#differences_with_python + +[locators-reference]: ../reference/locators.md +[packages-reference]: ../reference/packages.md +[run-args-reference]: ../reference/packages.md#arguments +[starlark-instructions-reference]: ../reference/starlark-instructions.md +[multi-phase-runs-reference]: ../reference/multi-phase-runs.md +[multi-phase-runs-explanation]: ../explanations/why-multi-phase-runs.md +[plan-reference]: ../reference/plan.md +[quickstart]: ../quickstart.md#write-a-simple-starlark-script \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/explanations/what-is-kurtosis.md b/docs/versioned_docs/version-0.70.6/explanations/what-is-kurtosis.md new file mode 100644 index 0000000000..ee97f3f2bd --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/what-is-kurtosis.md @@ -0,0 +1,20 @@ +--- +title: What Is Kurtosis? +sidebar_label: What Is Kurtosis? +sidebar_position: 1 +--- + +Kurtosis is a distributed application development platform. Its goal is to make building a distributed application as easy as developing a single-server app. + +Our philosophy is that the distributed nature of modern software means that modern software development now happens at the environment level. Spinning up a single service container in isolation is difficult because it has implicit dependencies on other resources: services, volume data, secrets, certificates, and network rules. Therefore, the environment - not the container - is the fundamental unit of modern software. + +This fact becomes apparent when we look at the software development lifecycle. Developers used to write code on their machine and ship a large binary to a few long-lived, difficult-to-maintain environments like Prod or Staging. Now, the decline of on-prem hardware, rise of containerization, and availability of flexible cloud compute enable the many environments of today: Prod, pre-Prod, Staging, Dev, and even ephemeral preview, CI test, and local dev. + +The problem is that our tools are woefully outdated. The term "DevOps" was coined during the Agile revolution in the early 2000's. It signified making Dev responsible for end-to-end software delivery, rather than building software and throwing it over the wall to Ops to run. The idea was to shorten feedback loops, and it worked. However, our systems have become so complex that companies are now hiring "DevOps engineers" to manage the Docker, AWS, Terraform, and Kubernetes underlying all modern software. Though we call them "DevOps engineers", we are recreating Ops and separating Dev and Ops once more. + +In our vision, a developer should have a single platform for prototyping, testing, debugging, deploying to Prod, and observing the live system. Our goal with Kurtosis is to bring DevOps back. + +To read more about our beliefs on reusable environments, [go here][reusable-environment-definitions]. To get started using Kurtosis, see [the quickstart][quickstart]. + +[reusable-environment-definitions]: ./reusable-environment-definitions.md +[quickstart]: ../quickstart.md diff --git a/docs/versioned_docs/version-0.70.6/explanations/why-multi-phase-runs.md b/docs/versioned_docs/version-0.70.6/explanations/why-multi-phase-runs.md new file mode 100644 index 0000000000..6c9dc5b38b --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/explanations/why-multi-phase-runs.md @@ -0,0 +1,40 @@ +--- +title: Why Multi-Phase Runs? +sidebar_label: Why Multi-Phase Runs? +--- + +Kurtosis runs its [Starlark environment definitions][starlark-explanation] in [multiple phases][multi-phase-runs-reference]. + +This can create pitfalls for users not accustomed to the multi-phase idea. For example, the following code has a bug: + +```python +service = add_service( + "my-service", + config = struct( + image = "hello-world", + ) +) + +if service.ip_address == "1.2.3.4": + print("IP address matched") +``` + +The `if` statement will never evaluate to true because `service.ip_address` is in fact a [future reference string][future-references-reference] that will never equal `1.2.3.4`. + +We chose this multi-phase approach despite its complexity because it provides significant advantages over traditional scripting: + +- Kurtosis can show the user the plan to execute before any changes are made. +- Kurtosis can validate the entire plan, saving the user from errors like container image typos, service name typos, and port typos before any changes are made. +- Kurtosis can optimize performance (e.g. downloading all container images before anything is executed, which is especially important on timing-sensitive tests). + +In the future, the multi-phase approach will also: + +- Give the user the power to have new services defined in the plan depend on existing services already running in the enclave. +- Give the user the power to remove and edit parts of the plan they don't like (useful when consuming third-party definitions). +- Allow users to "time-travel" through the plan, discovering what the environment will look like at any point during plan execution. +- Permit compiling a Kurtosis plan down to an idempotent, declarative format (e.g. Helm, Terraform, or Docker Compose). + + +[starlark-explanation]: ./starlark.md +[multi-phase-runs-reference]: ../reference/multi-phase-runs.md +[future-references-reference]: ../reference/future-references.md diff --git a/docs/versioned_docs/version-0.70.6/guides/adding-command-line-completion.md b/docs/versioned_docs/version-0.70.6/guides/adding-command-line-completion.md new file mode 100644 index 0000000000..cb14c46f18 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/guides/adding-command-line-completion.md @@ -0,0 +1,140 @@ +--- +title: Adding Command-Line Completion +sidebar_label: Adding Command-Line Completion +--- + + + + + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + +[The Kurtosis CLI](../reference/cli/cli.md) supports command-line completion for `bash`, `zsh`, and `fish`. With completion installed, you will be able to: + +- Complete subcommands (e.g. typing `kurtosis` and pressing TAB will suggest subcommands) +- Complete dynamic arguments (e.g. typing `kurtosis enclave inspect` and pressing TAB will list the names of existing enclaves if any) + +The process for installing completion is specific to each shell: + + + + +1. Print your Bash version: + ```bash + bash --version + ``` +1. If your Bash version is less than 4.1, upgrade it: + * On Mac, upgrade Mac via Homebrew: + ```bash + brew install bash + ``` + * On Linux, [upgrade it via the package manager for your distro](https://www.configserverfirewall.com/linux-tutorials/update-bash-linux/) +1. Check if you have [bash-completion](https://github.com/scop/bash-completion) installed: + ```bash + type _init_completion + ``` +1. If you get an error like `-bash: type: _init_completion: not found`, install Bash completion: + * On Mac: + 1. Install the completion library: + ```bash + brew install bash-completion@2 + ``` + 1. Add the following to your `~/.bash_profile`: + ```bash + export BREW_PREFIX="$(brew --prefix)" + [[ -r "${BREW_PREFIX}/etc/profile.d/bash_completion.sh" ]] && source "${BREW_PREFIX}/etc/profile.d/bash_completion.sh" + ``` + 1. Close and re-open your terminal window to reload your shell. + 1. Verify that you now have the completion installed: + ```bash + type _init_completion + ``` + * On Linux, install it using the package manager for your distro using [these installation instructions](https://github.com/scop/bash-completion#installation) +1. Skip this step if you are installing using Homebrew and have `bash-completion@2` installed. Otherwise, proceed to source the output of `kurtosis completion bash` in your Bash config file: + * On Mac, add the following to your `~/.bash_profile` file: + ```bash + # Add Kurtosis command-line completion + source <(kurtosis completion bash) + ``` + * On Linux, add the following to your `~/.bashrc` file: + ```bash + # Add Kurtosis command-line completion + source <(kurtosis completion bash) + ``` +1. If you have an alias set up for Kurtosis, add completion for that as well (we'll assume the alias `kt` in the examples below): + * On Mac, add the following to your `~/.bash_profile` file: + ```bash + # Add command-line completion to Kurtosis alias + complete -F __start_kurtosis kt + ``` + * On Linux, add the following to your `~/.bashrc` file: + ```bash + # Add command-line completion to Kurtosis alias + complete -F __start_kurtosis kt + ``` +1. Close and re-open your terminal window to reload your shell and apply the changes. + + + + + +1. Add the following to your `~/.zshrc` file: + ```zsh + # Add Kurtosis command-line completion + source <(kurtosis completion zsh) + compdef _kurtosis kurtosis + ``` +1. If you have an alias set up for Kurtosis, add the following to your `~/.zshrc` file (we'll assume the alias `kt` in this example): + ```zsh + # Add command-line completion to Kurtosis alias + compdef __start_kurtosis kt + ``` +1. Close and re-open your terminal window to reload your shell and apply the changes. +1. If you get an error like `complete:13: command not found: compdef`, add the following to the top of your `~/.zshrc` and close and re-open your terminal window to reload your shell: + ```zsh + autoload -Uz compinit + compinit + ``` + + + + +1. Add the following to your `~/.config/fish/config.fish` file: + ```fish + # Add Kurtosis command-line completion + kurtosis completion fish | source + ``` +1. Close and re-open your terminal window to reload your shell and apply the changes. + + + + +If necessary, tab completion can be installed manually in two steps as follows, by first generating the +tab completion code (specific to the shell) and then sourcing that code into the shell. + +1. The code needed to enable tab completion can be generated by the `kurtosis` cli by + running `kurtosis completion ` command, e.g. for `bash`: + ``` + kurtosis completion bash + ``` + +1. `source`ing the output of the command will enable command-line completion, and adding the `source` + command to your shell config file will enable it across shell instances. + ``` + # Add Kurtosis command-line completion to your shell config file + source <(kurtosis completion bash) + ``` + + + diff --git a/docs/versioned_docs/version-0.70.6/guides/installing-historical-versions.md b/docs/versioned_docs/version-0.70.6/guides/installing-historical-versions.md new file mode 100644 index 0000000000..b8a8f3c254 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/guides/installing-historical-versions.md @@ -0,0 +1,95 @@ +--- +title: Installing Historical Versions +sidebar_label: Installing Historical Versions +slug: /install-historical +sidebar_position: 3 +--- + + + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + +Occasionally, using historical versions of Kurtosis is necessary. For example, when working with a [Starlark](../explanations/starlark.md) Kurtosis package that was initially developed with an older version of Kurtosis, we might want rollback our Kurtosis version to ensure the version of Kurtosis we are running is compatible with the Kurtosis package. + +The instructions in this guide will walk you through installing and using a historical version of Kurtosis. To see what versions are available, reference our [changelog](../changelog.md). + +If you're looking to install the latest version of Kurtosis, [see here][install-kurtosis]. + + + + + +1. Uninstall your current version of Kurtosis + ``` + brew uninstall kurtosis-tech/tap/kurtosis-cli + ``` + +2. Install an earlier version of Kurtosis (eg. `0.68.6`) + ``` + brew install kurtosis-tech/tap/kurtosis-cli@ + ``` + + + + +:::caution + +If you already have `kurtosis-cli` package installed, we recommend uninstalling it first using: + +```bash +sudo apt remove kurtosis-cli +``` + +::: + +```bash +echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list +sudo apt update +sudo apt remove kurtosis-cli +sudo apt install kurtosis-cli= -V +``` + + + + +:::caution + +If you already have `kurtosis-cli` package installed, we recommend uninstalling it first using: + +```bash +sudo yum remove kurtosis-cli +``` + +::: + +```bash +echo '[kurtosis] +name=Kurtosis +baseurl=https://yum.fury.io/kurtosis-tech/ +enabled=1 +gpgcheck=0' | sudo tee /etc/yum.repos.d/kurtosis.repo +sudo yum remove kurtosis-cli +sudo yum install kurtosis-cli- +``` + + + + +Download the appropriate artifact from [the release artifacts page][release-artifacts]. + + + + + +The Kurtosis CLI cannot be installed directly on Windows. Windows users are encouraged to use [Windows Subsystem for Linux (WSL)][windows-susbsystem-for-linux] to use Kurtosis. + + + + + + +[install-kurtosis]: ./installing-the-cli.md +[release-artifacts]: https://github.com/kurtosis-tech/kurtosis-cli-release-artifacts/releases diff --git a/docs/versioned_docs/version-0.70.6/guides/installing-the-cli.md b/docs/versioned_docs/version-0.70.6/guides/installing-the-cli.md new file mode 100644 index 0000000000..beabf32127 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/guides/installing-the-cli.md @@ -0,0 +1,107 @@ +--- +title: Installing Kurtosis +sidebar_label: Installing Kurtosis +slug: /install +sidebar_position: 1 +--- + + + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +The instructions in this guide will walk you through installing the latest version of Kurtosis. + +If you already have Kurtosis installed and you're looking to upgrade to latest, [see here][upgrade-guide]. + +If you're looking to install a historical version instead, [see here][install-historical-guide]. + +I. Install & Start Docker +----------------- + +1. If you don't already have Docker installed, follow the instructions [here][docker-install] to install the Docker application specific to your machine (e.g. Apple Intel, Apple M1, etc.). +1. Start the Docker daemon (e.g. open Docker Desktop) +1. Verify that Docker is running: + ```bash + docker image ls + ``` + +II. Install the CLI +------------------------- + + + + +``` +brew install kurtosis-tech/tap/kurtosis-cli +``` + +:::info +Homebrew might warn you that your Xcode is outdated or missing entirely. [This is a Homebrew requirement](https://docs.brew.sh/Installation), and has nothing to do with Kurtosis (which ships as prebuilt binaries). + +To install or update your Xcode, run: + +```bash +xcode-select --install +``` +::: + + + + +```bash +echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list +sudo apt update +sudo apt install kurtosis-cli +``` + + + + +```bash +echo '[kurtosis] +name=Kurtosis +baseurl=https://yum.fury.io/kurtosis-tech/ +enabled=1 +gpgcheck=0' | sudo tee /etc/yum.repos.d/kurtosis.repo +sudo yum install kurtosis-cli +``` + + + + +Download the appropriate artifact from [the release artifacts page][release-artifacts]. + + + + + +The Kurtosis CLI cannot be installed directly on Windows. Windows users are encouraged to use [Windows Subsystem for Linux (WSL)][windows-susbsystem-for-linux] to use Kurtosis. + + + + + +III. (Optional) Add command-line completion +-------------------------------- +Kurtosis supports command-line completion to allow completing subcommands and dynamic values (e.g. enclave name during `enclave inspect`). This isn't required, but we believe it significantly enhances the Kurtosis experience for those who are using . If you'd like to install it, see [these instructions][installing-command-line-completion]. + +Run the quickstart +------------------ +If you're new to Kurtosis, you might like the [quickstart][quickstart] as a good onboarding to get started with Kurtosis. + + +[cli-changelog]: ../changelog.md +[metrics-philosophy]: ../explanations/metrics-philosophy.md +[analytics-disable]: ../reference/cli/analytics-disable.md +[quickstart]: ../quickstart.md +[installing-command-line-completion]: ./adding-command-line-completion.md +[install-historical-guide]: ./installing-historical-versions.md +[upgrade-guide]: ./upgrading-the-cli.md + +[release-artifacts]: https://github.com/kurtosis-tech/kurtosis-cli-release-artifacts/releases +[windows-susbsystem-for-linux]: https://learn.microsoft.com/en-us/windows/wsl/ +[docker-install]: https://docs.docker.com/get-docker/ diff --git a/docs/versioned_docs/version-0.70.6/guides/running-in-ci.md b/docs/versioned_docs/version-0.70.6/guides/running-in-ci.md new file mode 100644 index 0000000000..ab583df019 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/guides/running-in-ci.md @@ -0,0 +1,55 @@ +--- +title: Running Kurtosis in CI +sidebar_label: Running in CI +slug: /ci +--- + +Running Kurtosis on your local machine is nice, but executing it as part of CI is even better. This guide will walk you through modifying your CI config file to use Kurtosis in your CI environment: + +I. Installing The CLI +---------------------------- +You'll need the Kurtosis CLI inside your CI environment. This can be accomplished by following [the installation instructions](installing-the-cli.md) for whichever package manager your CI container uses. E.g. if you're using Github Actions with an Ubuntu executor, you'd add the instructions for installing the Kurtosis CLI via the `apt` package manager to your CI config file. + +II. Start The Engine +---------------------------- +You'll need the Kurtosis engine to be running to interact with Kurtosis, both via the [CLI](../reference/cli/cli.md) and the [SDK](../reference/sdk.md). Add `kurtosis engine start` in your CI config file after the CLI installation commands so that your Kurtosis commands work. + +III. Run Your Custom Logic +--------------------------------- +This will be specific to whatever you want to run in CI. E.g. if you have Javascript Mocha tests that use Kurtosis, you'd put that in your CI config file after installing the Kurtosis CLI & starting the engine. + +IV. Capturing Enclave Output +----------------------------------- +Naturally, if your job fails you'll want to see what was going on inside of Kurtosis at the time of failure. The `kurtosis enclave dump` command allows us to capture container logs & specs from an enclave, so that we can dump the state of the enclaves and attach them to the CI job for further debugging. The specifics of how to attach files to a CI job from within the job will vary depending on which CI provider you're using, but will look something like the following (which is for CircleCI): + +```yaml + # Run our custom logic (in this case, running a package), but don't exit immediately if it fails so that + # we can upload the 'enclave dump' results before the CI job ends + - run: | + if ! kurtosis run --enclave-name my-enclave github.com/kurtosis-tech/datastore-army-package; then + touch /tmp/testsuite-failed + fi + + # Dump enclave data so we can debug any issues that arise + - run: | + cd /tmp + + # Write enclave information to /tmp/my-enclave + kurtosis enclave dump my-enclave my-enclave + + # Zip up the data so we can attach it to the CI job + zip -r my-enclave.zip my-enclave + + # Attach the ZIP file to the CI job + - store_artifacts: + path: /tmp/my-enclave.zip + destination: my-enclave.zip + + # Now that we've uploaded the enclave data, fail the job if the testsuite failed + - run: "! [ -f /tmp/testsuite-failed ]" +``` + +Example +------- +- [CircleCI](https://github.com/kurtosis-tech/eth2-package/blob/main/.circleci/config.yml#L19) +- More CI examples coming soon... diff --git a/docs/versioned_docs/version-0.70.6/guides/simulating-networking-failure.md b/docs/versioned_docs/version-0.70.6/guides/simulating-networking-failure.md new file mode 100644 index 0000000000..7870565ad5 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/guides/simulating-networking-failure.md @@ -0,0 +1,181 @@ +--- +title: Simulating A Networking Failure +sidebar_label: Simulating a networking failure +--- + +Using Kurtosis you can control which services can communicate inside and across [subnetworks][subnetworks-reference]. Kurtosis provides arbitrarily fine grained control over which services can communicate with each other. This can be useful to simulate network faults, [partition tolerance][cap-theorem] or even partial network outages, including package drops. + +This guide illustrates the concept of Kurtosis subnetworks by simluating a partial networking failure within a distributed system. + +Step 1: Start all services in an enclave +----------------------------------------- + +The example system is composed of a Cassandra cluster with 3 nodes, 2 redundant services serving the main application and a single port proxy to load balance the requests. + +```python +MAIN_SUBNETWORK = "main_subnetwork" +SECONDARY_SUBNETWORK = "secondary_subnetwork" + +def run(args): + add_service( + service_name="cassandra_node_1", + config=ServiceConfig( + ... + subnetwork=MAIN_SUBNETWORK, + ), + ) + add_service( + service_name="cassandra_node_2", + config=ServiceConfig( + ... + subnetwork=MAIN_SUBNETWORK, + ), + ) + add_service( + service_name="cassandra_node_3", + config=ServiceConfig( + ... + subnetwork=MAIN_SUBNETWORK, + ), + ) + add_service( + service_name="app_service_1", + config=ServiceConfig( + ... + subnetwork=MAIN_SUBNETWORK, + ), + ) + add_service( + service_name="app_service_2", + config=ServiceConfig( + ... + subnetwork=MAIN_SUBNETWORK, + ), + ) + add_service( + service_name="single_port_proxy", + config=ServiceConfig( + ... + subnetwork=MAIN_SUBNETWORK, + ), + ) +``` + +When all the services are added to the Kurtosis enclave, it will look something like: + +``` + Kurtosis enclave + ----------------------------------------------------- + | main_subnetwork | + |-----------------------------------------------------| + | | + | cassandra_node_1 | + | cassandra_node_2 | + | cassandra_node_3 | + | app_service_1 | + | app_service_2 | + | single_port_proxy | + | | + ----------------------------------------------------- +``` + +At the start, all connections are allowed. +- all the Cassandra nodes can communicate with each other +- the two services can reach all Cassandra nodes +- the single port proxy is playing its role of dispatching requests to both `app_service_1` and `app_service_2` + +Setp 2: Add a second subnetwork by updating services +---------------------------------------------------- + +Subnetworks make it easy to simulate a network failure that completely isolates `cassandra_node_2` and `app_service_2` from the rest of the system. + +First,`cassandra_node_2` and `app_service_2` need to be assigned to a distinct subnetwork, `secondary_subnetwork`. This can be done by updating those services. + +This can be done by "updating" those services. + +```python +MAIN_SUBNETWORK = "main_subnetwork" +SECONDARY_SUBNETWORK = "secondary_subnetwork" + +def run(args): + # ... + # all the services are added using the code snippet above + # ... + + update_service( + service_name="cassandra_node_2", + config=UpdateServiceConfig( + subnetwork=SECONDARY_SUBNETWORK, + ), + ) + update_service( + service_name="app_service_2", + config=UpdateServiceConfig( + subnetwork=SECONDARY_SUBNETWORK, + ), + ) +``` + +Kurtosis has the concept of a *default connection* between subnetworks. The default connection is the connection configuration that all pairs of subnetworks will inherit. At enclave creation, the default connection is set to allow communication between subnetworks. In this case, when the `cassandra_node_2` and `app_service_2` are assigned `secondary_subnetwork`, nothing changes. `main_subnetwork` and `secondary_subnetwork` can continue to communicate because the default connection is unblocked. + +``` + Kurtosis enclave + ----------------------------------------------------- + | main_subnetwork | secondary_subnetwork | + |-----------------------------------------------------| + | . | + | cassandra_node_1 . | + | . cassandra_node_2 | + | cassandra_node_3 . | + | app_service_1 . | + | . app_service_2 | + | single_port_proxy . | + | . | + ----------------------------------------------------- +``` + +Setp 3: Configure the connection between the two subnetworks +------------------------------------------------------------ + +The creation of `main_subnetwork` and `secondary_subnetwork` now makes it possible to reconfigure the connection between them. Communications between the two subnetworks can now be blocked partially or completely by overriding the default connection for those two specific subnetworks. + +```python +MAIN_SUBNETWORK = "main_subnetwork" +SECONDARY_SUBNETWORK = "secondary_subnetwork" + +def run(args): + # ... + # all the services are added and `cassandra_node_2` and `app_service_2` are updated using the code snippet above + # ... + + set_connection( + (MAIN_SUBNETWORK, SECONDARY_SUBNETWORK), + config=ConnectionConfig( + packet_loss_percentage=90.0, # 90% of the packet are dropped + ), + ) +``` + +The result is the following: `cassandra_node_2` and `app_service_2` are partially unreachable and the resilience of the system can be tested. + +``` + Kurtosis enclave + ----------------------------------------------------- + | main_subnetwork | secondary_subnetwork | + |-------------------------|---------------------------| + | | | + | cassandra_node_1 | | + | | cassandra_node_2 | + | cassandra_node_3 | | + | app_service_1 | | + | | app_service_2 | + | single_port_proxy | | + | | | + ----------------------------------------------------- +``` + + + +[subnetworks-reference]: ../reference/subnetworks.md + +[cap-theorem]: https://en.wikipedia.org/wiki/CAP_theorem diff --git a/docs/versioned_docs/version-0.70.6/guides/upgrading-the-cli.md b/docs/versioned_docs/version-0.70.6/guides/upgrading-the-cli.md new file mode 100644 index 0000000000..b6b02cff70 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/guides/upgrading-the-cli.md @@ -0,0 +1,88 @@ +--- +title: Upgrading Kurtosis +sidebar_label: Upgrading Kurtosis +slug: /upgrade +sidebar_position: 2 +--- + + + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + +The instructions in this guide assume you already have Kurtosis installed, and will walk you through upgrading to the latest version of Kurtosis. + +If you're looking to install Kurtosis, [see here][install-guide]. + +I. Check breaking changes +--------------------------------- +You can check the version of the CLI you're running with `kurtosis version`. Before upgrading to the latest version, check [the changelog to see if there are any breaking changes][cli-changelog] before proceeding with the steps below to upgrade. + +II. Upgrade the CLI +------------------------- + + + + +```bash +brew update && brew upgrade kurtosis-tech/tap/kurtosis-cli +``` + + + + +```bash +apt install --only-upgrade kurtosis-cli +``` + + + + +```bash +yum upgrade kurtosis-cli +``` + + + + +Download the appropriate artifact from [the release artifacts page][release-artifacts]. + + + + + +The Kurtosis CLI cannot be installed directly on Windows. Windows users are encouraged to use [Windows Subsystem for Linux (WSL)][windows-susbsystem-for-linux] to use Kurtosis. + + + + + +III. Restart the engine +----------------------- +If you upgraded the CLI through a minor version (the `Y` in a `X.Y.Z` version), you may need to restart your Kurtosis engine after the upgrade. + +If this is needed, the Kurtosis CLI will prompt you with an error like so: + +```text +The engine server API version that the CLI expects, 1.7.4, doesn't match the running engine server API version, 1.6.8; this would cause broken functionality so you'll need to restart the engine to get the correct version by running 'kurtosis engine restart' +``` + +The fix is to [restart the engine][kurtosis-engine-restart] like so: + +``` +kurtosis engine restart +``` + + +[install-guide]: ./installing-the-cli.md +[cli-changelog]: ../changelog.md +[metrics-philosophy]: ../explanations/metrics-philosophy.md +[quickstart]: ../quickstart.md +[installing-command-line-completion]: ./adding-command-line-completion.md + +[release-artifacts]: https://github.com/kurtosis-tech/kurtosis-cli-release-artifacts/releases +[windows-susbsystem-for-linux]: https://learn.microsoft.com/en-us/windows/wsl/ + +[kurtosis-engine-restart]: ../reference/cli/engine-restart.md diff --git a/docs/versioned_docs/version-0.70.6/home.md b/docs/versioned_docs/version-0.70.6/home.md new file mode 100644 index 0000000000..cf5b032a30 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/home.md @@ -0,0 +1,40 @@ +--- +title: Introduction +sidebar_label: Introduction +slug: '/' +sidebar_position: 1 +hide_table_of_contents: true +--- + +[Kurtosis](https://www.kurtosis.com) is a development platform for distributed applications that aims to provide a consistent experience across all stages of distributed app software delivery. + +Use cases for Kurtosis include: + +- Running a third-party distributed app, without knowing how to set it up +- Local prototyping & development on distributed apps +- Writing integration and end-to-end distributed app tests (e.g. happy path & sad path tests, load tests, performance tests, etc.) +- Running integration/E2E distributed app tests +- Debugging distributed apps during development + +## Why Kurtosis? + +Docker and Kubernetes are each great at serving developers in different parts of the development cycle: Docker for development/testing, Kubernetes for production. However, the separation between the two entails different distributed app definitions, and different tooling. In dev/test, this means Docker Compose and Docker observability tooling. In production, this means Helm definitions and manually-configured observability tools like Istio, Datadog, or Honeycomb. + +![Why Kurtosis](@site/static/img/home/kurtosis-utility.png) + +Kurtosis aims at one level of abstraction higher. Developers can define their distributed applications in Kurtosis, and Kurtosis will handle: + +With Kurtosis, developers can build with local sandbox environments that demonstrate how their code will work when integrated with the rest of the system. In addition, advanced end-to-end testing workflows are available to teams using the manipulation tooling in the Kurtosis engine runtime which allow them to do end-to-end testing like fault-tolerance, regression, and performance tests. + +- Running on Docker or Kubernetes +- Reproduceability +- Safety +- Port-forwarding & local development hookups +- Observability +- Sharing + +If we succeed in our vision, you will be able to use the same distributed application definition from local dev all the way to prod. + +:::info +If you have questions, need help, or simply want to learn more, schedule a live session with us, go [here](https://calendly.com/d/zgt-f2c-66p/kurtosis-onboarding). +::: diff --git a/docs/versioned_docs/version-0.70.6/quickstart.md b/docs/versioned_docs/version-0.70.6/quickstart.md new file mode 100644 index 0000000000..ea774f60a8 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/quickstart.md @@ -0,0 +1,1019 @@ +--- +title: Quickstart +sidebar_label: Quickstart +slug: /quickstart +--- + +Introduction +------------ + +Welcome to the [Kurtosis][homepage] quickstart! This guide will take ~15 minutes and will walk you through building a basic Kurtosis package. + +:::tip What You'll Do + +- Start a containerized Postgres database in Kurtosis +- Seed your database with test data using task sequencing +- Connect an API server to your database using dynamic service dependencies +- Parameterize your application setup in order to automate loading data into your API +::: + +
Getting help and giving feedback + +There are many ways to get help and give feedback. First, every Kurtosis command accepts a `-h` flag to print helptext. If that doesn't help, here are some ways to get support: + +- `kurtosis feedback "my feedback"` will take you to our [Github issue creation page](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) to file an issue with pre-filled text `my feedback`. Passing in `--bug` or `--docs` will take you to the specific Issue template for bug reports or docs issues, respectively +- `kurtosis feedback --calendly` opens a calendly link for a personal help session with [our cofounder Kevin][kevin-linked]. +- `kurtosis discord` command will open up our [Discord](https://discord.com/channels/783719264308953108/783719264308953111), where you can get live support via chat with our team. + +**Don't suffer in silence - we want to help and hear from you!** + +
+ +## Setup + +Before you proceed, make sure you have [Kurtosis installed][installing-kurtosis-guide] (or [upgraded to latest][upgrading-kurtosis-guide] if you already have it), Docker is started, and the Docker engine is running. + +Hello, World +------------ +First, create and `cd` into a directory to hold the project you'll be working on: + +```bash +mkdir kurtosis-quickstart && cd kurtosis-quickstart +``` + +:::tip +All code blocks in this quickstart can be copied by hovering over the block and clicking the clipboard that appears in the right. +::: + +Next, create a Starlark file called `main.star` inside your new directory with the following contents (more on Starlark in the "Review" section coming up soon): + +```python +def run(plan, args): + plan.print("Hello, world") +``` + +:::tip +If you're using Vim, you can add the following to your `.vimrc` to get Starlark syntax highlighting: + +``` +" Add syntax highlighting for Starlark files +autocmd FileType *.star setlocal filetype=python +``` + +::: + +Finally, [run][kurtosis-run-reference] the script (we'll explain enclaves in the "Review" section too): + +```bash +kurtosis run --enclave quickstart main.star +``` + +Kurtosis will work for a bit, and then deliver you results: + +```text +INFO[2023-03-15T04:27:01-03:00] Creating a new enclave for Starlark to run inside... +INFO[2023-03-15T04:27:05-03:00] Enclave 'quickstart' created successfully + +> print msg="Hello, world" +Hello, world + +Starlark code successfully run. No output was returned. +INFO[2023-03-15T04:27:05-03:00] =================================================== +INFO[2023-03-15T04:27:05-03:00] || Created enclave: quickstart || +INFO[2023-03-15T04:27:05-03:00] =================================================== +Name: quickstart +UUID: a78f2ce1ca68 +Status: RUNNING +Creation Time: Wed, 15 Mar 2023 04:27:01 -03 + +========================================= Files Artifacts ========================================= +UUID Name + +========================================== User Services ========================================== +UUID Name Ports Status +``` + +Congratulations - you've written your first Kurtosis code! + +### Review +:::info +We'll use these "Review" sections to explain what happened in the section. If you just want the action, feel free to skip them. +::: + +In this section, we created a `.star` file that prints `Hello, world`. The `.star` extension corresponds to [the Starlark language developed at Google][starlark-github-repo], a dialect of Python for configuring the [Bazel build system][bazel-github]. [Kurtosis uses Starlark for the same purpose of configuring builds][starlark-explanation], except that we're building a distributed application rather than binaries or JARs. + +When you ran the Starlark, you got `Created enclave: quickstart`. An [enclave][enclaves-explanation] is a Kurtosis primitive that can be thought of as an *ephemeral test environment*, on top of Docker or Kubernetes, for a distributed application. The distributed applications that you define with Starlark will run inside enclaves. + +Enclaves are intended to be easy to create, easy to destroy, cheap to run, and isolated from each other. Use enclaves liberally! + +Run Postgres +-------------- +The heart of any application is the database. To introduce you to Kurtosis, we'll start by launching a Postgres server using Kurtosis. + +Replace the contents of your `main.star` file with the following: + +```python +POSTGRES_PORT_ID = "postgres" +POSTGRES_DB = "app_db" +POSTGRES_USER = "app_user" +POSTGRES_PASSWORD = "password" + +def run(plan, args): + # Add a Postgres server + postgres = plan.add_service( + serivce_name = "postgres", + config = ServiceConfig( + image = "postgres:15.2-alpine", + ports = { + POSTGRES_PORT_ID: PortSpec(5432, application_protocol = "postgresql"), + }, + env_vars = { + "POSTGRES_DB": POSTGRES_DB, + "POSTGRES_USER": POSTGRES_USER, + "POSTGRES_PASSWORD": POSTGRES_PASSWORD, + }, + ), + ) +``` + +You're almost ready to run, but you still have the `quickstart` enclave hanging around from the previous section. [Blow it away][kurtosis-clean-reference] and rerun: + +```bash +kurtosis clean -a && kurtosis run --enclave quickstart main.star +``` + +:::info +This clean-and-run process will be your dev loop for the rest of the quickstart. +::: + +You'll see in the result that the `quickstart` enclave now contains a Postgres instance: + +```text +Name: quickstart +UUID: a30106a0bb87 +Status: RUNNING +Creation Time: Tue, 14 Mar 2023 20:23:54 -03 + +========================================= Files Artifacts ========================================= +UUID Name + +========================================== User Services ========================================== +UUID Name Ports Status +b6fc024deefe postgres postgres: 5432/tcp -> postgresql://127.0.0.1:59299 RUNNING +``` + +### Review +So what actually happened? + +1. **Interpretation:** Kurtosis ran your Starlark to build [a plan](https://docs.kurtosis.com/reference/plan) for what you wanted done (in this case, starting a Postgres instance) +1. **Validation:** Kurtosis ran several validations against your plan, including validating that the Postgres image exists +1. **Execution:** Kurtosis executed the validated plan inside the enclave to start a Postgres container + +Note that Kurtosis did not execute anything until _after_ Interpretation and Validation completed. You can think of Interpretation and Validation like Kurtosis' "compilation" for your distributed system: we can catch many errors before any containers run, which shortens the dev loop and reduces the resource burden on your machine. + +We call this approach [multi-phase runs][multi-phase-runs-reference]. While it has powerful benefits, the stumbling point for new Kurtosis users is that _you cannot reference Execution values like IP address in Starlark_ because they simply don't exist at Interpretation time. We'll see how to work around this limitation later. + +Add some data +------------- +A database without data is a fancy heater, so let's add some. + +Our two options for seeding a Postgres database are: + +1. Making a sequence of PSQL commands via the `psql` binary +1. Using `pg_restore` to load a package of data + +Both are possible in Kurtosis, but for this tutorial we'll do the second one using a seed data TAR of DVD rental information, [courtesy of postgresqltutorial.com](https://www.postgresqltutorial.com/postgresql-getting-started/postgresql-sample-database/). + +Normally seeding a database would require downloading the seed data to your machine, starting Postgres, and writing a pile of Bash to copy the seed data to the Postgres server and run a `pg_restore`. If you forgot to check if the database is available, you may get flakes when you try to use the seeding logic in a test. + +You could try Docker Compose to volume-mount the data TAR into the Postgres server, but you'd still need to handle Postgres availability and sequencing the `pg_restore` afterwards. + +By contrast, Kurtosis Starlark scripts can use data as a first-class primitive and sequence tasks such as `pg_restore` into the plan. + +Let's see it in action, and we'll explain what's happening afterwards. + +Replace your `main.star` with the following: + +```python +data_package_module = import_module("github.com/kurtosis-tech/awesome-kurtosis/data-package/main.star") + +POSTGRES_PORT_ID = "postgres" +POSTGRES_DB = "app_db" +POSTGRES_USER = "app_user" +POSTGRES_PASSWORD = "password" + +SEED_DATA_DIRPATH = "/seed-data" + +def run(plan, args): + # Make data available for use in Kurtosis + data_package_module_result = data_package_module.run(plan, struct()) + + # Add a Postgres server + postgres = plan.add_service( + service_name = "postgres", + config = ServiceConfig( + image = "postgres:15.2-alpine", + ports = { + POSTGRES_PORT_ID: PortSpec(5432, application_protocol = "postgresql"), + }, + env_vars = { + "POSTGRES_DB": POSTGRES_DB, + "POSTGRES_USER": POSTGRES_USER, + "POSTGRES_PASSWORD": POSTGRES_PASSWORD, + }, + files = { + SEED_DATA_DIRPATH: data_package_module_result.files_artifact, + } + ), + ) + + # Wait for Postgres to become available + postgres_flags = ["-U", POSTGRES_USER,"-d", POSTGRES_DB] + plan.wait( + service_name = "postgres", + recipe = ExecRecipe(command = ["psql"] + postgres_flags + ["-c", "\\l"]), + field = "code", + assertion = "==", + target_value = 0, + timeout = "5s", + ) + + # Load the data into Postgres + plan.exec( + service_name = "postgres", + recipe = ExecRecipe(command = ["pg_restore"] + postgres_flags + [ + "--no-owner", + "--role=" + POSTGRES_USER, + SEED_DATA_DIRPATH + "/" + data_package_module_result.tar_filename, + ]), + ) +``` + +Next to your `main.star`, add a file called `kurtosis.yml` with the following contents: + +```bash +name: "github.com/john-snow/kurtosis-quickstart" +``` + +Rerun: + +```bash +kurtosis clean -a && kurtosis run --enclave quickstart . +``` + +(Note that the final argument is now `.` and not `main.star`) + +The output should also look more interesting as our plan has grown bigger: + +```text +INFO[2023-03-15T04:34:06-03:00] Cleaning enclaves... +INFO[2023-03-15T04:34:06-03:00] Successfully removed the following enclaves: +60601dd9906e40d6af5f16b233a56ae7 quickstart +INFO[2023-03-15T04:34:06-03:00] Successfully cleaned enclaves +INFO[2023-03-15T04:34:06-03:00] Cleaning old Kurtosis engine containers... +INFO[2023-03-15T04:34:06-03:00] Successfully cleaned old Kurtosis engine containers +INFO[2023-03-15T04:34:06-03:00] Creating a new enclave for Starlark to run inside... +INFO[2023-03-15T04:34:10-03:00] Enclave 'quickstart' created successfully +INFO[2023-03-15T04:34:10-03:00] Executing Starlark package at '/tmp/kurtosis-quickstart' as the passed argument '.' looks like a directory +INFO[2023-03-15T04:34:10-03:00] Compressing package 'github.com/YOUR-GITHUB-USERNAME/kurtosis-quickstart' at '.' for upload +INFO[2023-03-15T04:34:10-03:00] Uploading and executing package 'github.com/YOUR-GITHUB-USERNAME/kurtosis-quickstart' + +> upload_files src="github.com/kurtosis-tech/awesome-kurtosis/data-package/dvd-rental-data.tar" +Files with artifact name 'howling-thunder' uploaded with artifact UUID '32810fc8c131414882c52b044318b2fd' + +> add_service service_name="postgres" config=ServiceConfig(image="postgres:15.2-alpine", ports={"postgres": PortSpec(number=5432, application_protocol="postgresql")}, files={"/seed-data": "howling-thunder"}, env_vars={"POSTGRES_DB": "app_db", "POSTGRES_PASSWORD": "password", "POSTGRES_USER": "app_user"}) +Service 'postgres' added with service UUID 'f1d9cab2ca344d1fbb0fc00b2423f45f' + +> wait recipe=ExecRecipe(command=["psql", "-U", "app_user", "-d", "app_db", "-c", "\\l"]) field="code" assertion="==" target_value=0 timeout="5s" +Wait took 2 tries (1.135498667s in total). Assertion passed with following: +Command returned with exit code '0' and the following output: +-------------------- + List of databases + Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges +-----------+----------+----------+------------+------------+------------+-----------------+----------------------- + app_db | app_user | UTF8 | en_US.utf8 | en_US.utf8 | | libc | + postgres | app_user | UTF8 | en_US.utf8 | en_US.utf8 | | libc | + template0 | app_user | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/app_user + + | | | | | | | app_user=CTc/app_user + template1 | app_user | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/app_user + + | | | | | | | app_user=CTc/app_user +(4 rows) + + +-------------------- + +> exec recipe=ExecRecipe(command=["pg_restore", "-U", "app_user", "-d", "app_db", "--no-owner", "--role=app_user", "/seed-data/dvd-rental-data.tar"]) +Command returned with exit code '0' with no output + +Starlark code successfully run. No output was returned. +INFO[2023-03-15T04:34:21-03:00] =================================================== +INFO[2023-03-15T04:34:21-03:00] || Created enclave: quickstart || +INFO[2023-03-15T04:34:21-03:00] =================================================== +Name: quickstart +UUID: 995fe0ca69fe +Status: RUNNING +Creation Time: Wed, 15 Mar 2023 04:34:06 -03 + +========================================= Files Artifacts ========================================= +UUID Name +323c9a71ebbf crimson-haze + +========================================== User Services ========================================== +UUID Name Ports Status +f1d9cab2ca34 postgres postgres: 5432/tcp -> postgresql://127.0.0.1:62914 RUNNING +``` + +Does our Postgres have data now? Let's find out by logging into the database: + +```bash +kurtosis service shell quickstart postgres +``` + +This will open a shell on the Postgres container. From there, listing the tables in the Postgres... + +``` bash +psql -U app_user -d app_db -c '\dt' +``` + +...will reveal that many new tables now exist: + +```text + List of relations + Schema | Name | Type | Owner +--------+---------------+-------+---------- + public | actor | table | app_user + public | address | table | app_user + public | category | table | app_user + public | city | table | app_user + public | country | table | app_user + public | customer | table | app_user + public | film | table | app_user + public | film_actor | table | app_user + public | film_category | table | app_user + public | inventory | table | app_user + public | language | table | app_user + public | payment | table | app_user + public | rental | table | app_user + public | staff | table | app_user + public | store | table | app_user +(15 rows) +``` + +Feel free to explore the Postgres container. When you're done run either `exit` or press Ctrl-D. + +### Review +So what did we just do? + +Kurtosis' first-class data primitive is called a [files artifact][files-artifacts-reference]. Each files artifact is a TGZ of arbitrary files, living inside the enclave. So long as a files artifact exists, Kurtosis knows how to mount its contents on a service. We used this feature to mount the seed data into the Postgres instance via the `ServiceConfig.files` option: + +```python +postgres = plan.add_service( + service_name = "postgres", + config = ServiceConfig( + # ...omitted... + files = { + SEED_DATA_DIRPATH: data_package_module_result.files_artifact, + } + ), +) +``` + +But where did the data come from? + +There are many ways to create files artifacts in an enclave. The simplest is to upload files from your local machine using [the `kurtosis files upload` command][kurtosis-files-upload-reference]. A more advanced way is to upload files using [the `upload_files` Starlark instruction][upload-files-reference] on the plan. + +But... **you never downloaded the seed data on your local machine. In fact, you didn't need you to because we leveraged one of the most powerful features of Kurtosis: composition.** + +Kurtosis has [a built-in packaging/dependency system][how-do-imports-work-explanation] that allows Starlark code to depend on other Starlark code via Github repositories. When you created the `kurtosis.yml` file, you linked your code into the packaging system: you told Kurtosis that your code is a part of a [Kurtosis package][packages-reference], which allowed your code to depend on external Starlark code. + +This line at the top of your `main.star`... + +```python +data_package_module = import_module("github.com/kurtosis-tech/awesome-kurtosis/data-package/main.star") +``` + +...created a dependency on [the external Kurtosis package living here][data-package-example]. + +Your code then called that external dependency here... + +```python +data_package_module_result = data_package_module.run(plan, struct()) +``` + +...which in turn locally ran [the code in the `main.star` of that external package][data-package-example-main.star]. That external Kurtosis package happens to contain [the seed data][data-package-example-seed-tar], and it uses the `upload_data` Starlark instruction on the plan to make the seed data available via a files artifact to your local `main.star` file that we've been editing. From there, all we needed to do was mount it on the `postgres` service. + +This ability to modularize your distributed application logic using only a Github repo is one of Kurtosis' most loved features. We won't dive into all the usecases now, but [the examples here][awesome-kurtosis-repo] can serve as a good source of inspiration. + + +Add an API +---------- +Databases don't come alone, however. In this section we'll add a [PostgREST API][postgrest] in front of the database and see how Kurtosis handles inter-service dependencies. + +Replace the contents of your `main.star` with this: + +```python +data_package_module = import_module("github.com/kurtosis-tech/awesome-kurtosis/data-package/main.star") + +POSTGRES_PORT_ID = "postgres" +POSTGRES_DB = "app_db" +POSTGRES_USER = "app_user" +POSTGRES_PASSWORD = "password" + +SEED_DATA_DIRPATH = "/seed-data" + +POSTGREST_PORT_ID = "http" + +def run(plan, args): + # Make data available for use in Kurtosis + data_package_module_result = data_package_module.run(plan, struct()) + + # Add a Postgres server + postgres = plan.add_service( + service_name = "postgres", + config = ServiceConfig( + image = "postgres:15.2-alpine", + ports = { + POSTGRES_PORT_ID: PortSpec(5432, application_protocol = "postgresql"), + }, + env_vars = { + "POSTGRES_DB": POSTGRES_DB, + "POSTGRES_USER": POSTGRES_USER, + "POSTGRES_PASSWORD": POSTGRES_PASSWORD, + }, + files = { + SEED_DATA_DIRPATH: data_package_module_result.files_artifact, + } + ), + ) + + # Wait for Postgres to become available + postgres_flags = ["-U", POSTGRES_USER,"-d", POSTGRES_DB] + plan.wait( + service_name = "postgres", + recipe = ExecRecipe(command = ["psql"] + postgres_flags + ["-c", "\\l"]), + field = "code", + assertion = "==", + target_value = 0, + timeout = "5s", + ) + + # Load the data into Postgres + plan.exec( + service_name = "postgres", + recipe = ExecRecipe(command = ["pg_restore"] + postgres_flags + [ + "--no-owner", + "--role=" + POSTGRES_USER, + SEED_DATA_DIRPATH + "/" + data_package_module_result.tar_filename, + ]), + ) + + # Add PostgREST + postgres_url = "postgresql://{}:{}@{}:{}/{}".format( + "postgres", + POSTGRES_PASSWORD, + postgres.ip_address, + postgres.ports[POSTGRES_PORT_ID].number, + POSTGRES_DB, + ) + api = plan.add_service( + service_name = "api", # Naming our PostgREST service "api" + config = ServiceConfig( + image = "postgrest/postgrest:v10.2.0.20230209", + env_vars = { + "PGRST_DB_URI": postgres_url, + "PGRST_DB_ANON_ROLE": POSTGRES_USER, + }, + ports = {POSTGREST_PORT_ID: PortSpec(3000, application_protocol = "http")}, + ) + ) + + # Wait for PostgREST to become available + plan.wait( + service_name = "api", + recipe = GetHttpRequestRecipe( + port_id = POSTGREST_PORT_ID, + endpoint = "/actor?limit=5", + ), + field = "code", + assertion = "==", + target_value = 200, + timeout = "5s", + ) +``` + +Now, run the same dev loop command as before (and don't worry about the result!): + +```bash +kurtosis clean -a && kurtosis run --enclave quickstart . +``` + +We just got a failure, just like we might when building a real system! + +```text +> wait recipe=GetHttpRequestRecipe(port_id="http", endpoint="/actor", extract="") field="code" assertion="==" target_value=200 timeout="5s" +There was an error executing Starlark code +An error occurred executing instruction (number 6) at github.com/ME/kurtosis-quickstart[77:14]: +wait(recipe=GetHttpRequestRecipe(port_id="http", endpoint="/actor", extract=""), field="code", assertion="==", target_value=200, timeout="5s", service_name="api") + --- at /home/circleci/project/core/server/api_container/server/startosis_engine/startosis_executor.go:62 (StartosisExecutor.Execute.func1) --- +Caused by: Wait timed-out waiting for the assertion to become valid. Waited for '8.183602629s'. Last assertion error was: + + --- at /home/circleci/project/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go:263 (WaitCapabilities.Execute) --- + +Error encountered running Starlark code. +``` + +Here, Kurtosis is telling us that the `wait` instruction on line `77` of our `main.star` (the one for ensuring PostgREST is up) is timing out. + +The enclave state is usually a good place to start. If we look at the bottom of our output we'll see the following state of the enclave: + +```text + +Name: quickstart +UUID: 5b360f940bcc +Status: RUNNING +Creation Time: Tue, 14 Mar 2023 22:15:19 -03 + +========================================= Files Artifacts ========================================= +UUID Name +323c9a71ebbf crimson-haze + +========================================== User Services ========================================== +UUID Name Ports Status +45b355fc810b postgres postgres: 5432/tcp -> postgresql://127.0.0.1:59821 RUNNING +80987420176f api http: 3000/tcp STOPPED +``` + +The problem is clear now: the PostgREST (we named it `api`) service status is `STOPPED` rather than `RUNNING`. When we grab the PostgREST logs... + +```bash +kurtosis service logs quickstart api +``` + +...we can see that the PostgREST is dying: + +```text +15/Mar/2023:01:15:30 +0000: Attempting to connect to the database... +15/Mar/2023:01:15:30 +0000: {"code":"PGRST000","details":"FATAL: password authentication failed for user \"postgres\"\n","hint":null,"message":"Database connection error. Retrying the connection."} +15/Mar/2023:01:15:30 +0000: FATAL: password authentication failed for user "postgres" + +postgrest: thread killed +``` + +Looking back to our Starlark, we can see the problem: we're creating the Postgres database with a user called `app_user`, but we're telling PostgREST to try and connect through a user called `postgres`: + +```python +POSTGRES_USER = "app_user" + +# ... + +def run(plan, args): + # ... + + # Add a Postgres server + postgres = plan.add_service( + service_name = "postgres", + config = ServiceConfig( + # ... + env_vars = { + # ... + "POSTGRES_USER": POSTGRES_USER, + # ... + }, + # ... + ), + ) + + # ... + + postgres_url = "postgresql://{}:{}@{}:{}/{}".format( + "postgres", # <---------- THE PROBLEM + POSTGRES_PASSWORD, + postgres.ip_address, + postgres.ports[POSTGRES_PORT_ID].number, + POSTGRES_DB, + ) +``` + +In the line declaring the `postgres_url` variable in your `main.star` file, replace the `"postgres"` string with `POSTGRES_USER` to use the correct username we specified at the beginning of our file. Then rerun your dev loop: + +```bash +kurtosis clean -a && kurtosis run --enclave quickstart . +``` + +Now at the bottom of the output we can see that the PostgREST service is `RUNNING` correctly: + +```text +Name: quickstart +UUID: 11c0ac047299 +Status: RUNNING +Creation Time: Tue, 14 Mar 2023 22:30:02 -03 + +========================================= Files Artifacts ========================================= +UUID Name +323c9a71ebbf crimson-haze + +========================================== User Services ========================================== +UUID Name Ports Status +ce90b471a982 postgres postgres: 5432/tcp -> postgresql://127.0.0.1:59883 RUNNING +98094b33cd9a api http: 3000/tcp -> http://127.0.0.1:59887 RUNNING +``` + +### Review +In this section, we declared a new PostgREST service (that we named `api` for readability) with a dependency on the Postgres service. + +Yet... PostgREST needs to know the IP address or hostname of the Postgres service, and we said earlier that Starlark (the Interpretation phase) can never know Execution values. How can this be? + +Answer: Execution-time values are represented at Interpretation time as [future references][future-references-reference] - special Starlark strings like `{{kurtosis:6670e781977d41409f9eb2833977e9df:ip_address.runtime_value}}` that Kurtosis will replace at Execution time with the actual value. In this case, the `postgres_url` variable here... + +```python +postgres_url = "postgresql://{}:{}@{}:{}/{}".format( + POSTGRES_USER, + POSTGRES_PASSWORD, + postgres.ip_address, + postgres.ports[POSTGRES_PORT_ID].number, + POSTGRES_DB, +) +``` + +...used the `postgres.ip_address` and `postgres.ports[POSTGRES_PORT_ID].number` future references returned by adding the Postgres service, so that when `postgres_url` was used as an environment variable during PostgREST startup... + +```python +api = plan.add_service( + service_name = "api", # Naming our PostgREST service "api" + config = ServiceConfig( + # ... + env_vars = { + "PGRST_DB_URI": postgres_url, # <-------- HERE + "PGRST_DB_ANON_ROLE": POSTGRES_USER, + }, + # ... + ) +) +``` + +...Kurtosis simply swapped in the correct Postgres container Execution-time values. While future references take some getting used to, [we've found the feedback loop speedup to be very worth it][why-multi-phase-runs-explanation]. + +Modifying data +-------------- +Now that we have an API, we should be able to interact with the data. + +[Inspect][kurtosis-enclave-inspect-reference] your enclave: + +```bash +kurtosis enclave inspect quickstart +``` + +Notice how Kurtosis automatically exposed the PostgREST container's `http` port to your machine: + +```text +28a923400e50 api http: 3000/tcp -> http://127.0.0.1:59992 RUNNING +``` + +:::info +In this output the `http` port is exposed as URL `http://127.0.0.1:59992`, but your port number will be different. +::: + +You can paste the URL from your output into your browser (or Cmd+click if you're using [iTerm][iterm]) to verify that you are indeed talking to the PostgREST inside your `quickstart` enclave: + +```json +{"swagger":"2.0","info":{"description":"","title":"standard public schema","version":"10.2.0.20230209 (pre-release) (a1e2fe3)"},"host":"0.0.0.0:3000","basePath":"/","schemes":["http"],"consumes":["application/json","application/vnd.pgrst.object+json","text/csv"],"produces":["application/json","application/vnd.pgrst.object+json","text/csv"],"paths":{"/":{"get":{"tags":["Introspection"],"summary":"OpenAPI description (this document)","produces":["application/openapi+json","application/json"],"responses":{"200":{"description":"OK"}}}},"/actor":{"get":{"tags":["actor"],"parameters":[{"$ref":"#/parameters/rowFilter.actor.actor_id"},{"$ref":"#/parameters/rowFilter.actor.first_name"},{"$ref":"#/parameters/rowFilter.actor.last_name"},{"$ref":"#/parameters/rowFilter.actor.last_update"},{"$ref":"#/parameters/select"},{"$ref":"#/parameters/order"},{"$ref":"#/parameters/range"},{"$ref":"#/parameters/rangeUnit"},{"$ref":"#/parameters/offset"},{"$ref":"#/parameters/limit"},{"$ref":"#/parameters/preferCount"}], ... +``` + +Now make a request to insert a row into the database (replacing `$YOUR_PORT` with the `http` port from your `enclave inspect` output for the PostgREST service that we named `api`)... + +```bash +curl -XPOST -H "content-type: application/json" http://127.0.0.1:$YOUR_PORT/actor --data '{"first_name": "Kevin", "last_name": "Bacon"}' +``` + +...and then query for it (again replacing `$YOUR_PORT` with your port)... + +```bash +curl -XGET "http://127.0.0.1:$YOUR_PORT/actor?first_name=eq.Kevin&last_name=eq.Bacon" +``` + +...to get it back: + +```text +[{"actor_id":201,"first_name":"Kevin","last_name":"Bacon","last_update":"2023-03-15T02:08:14.315732"}] +``` + +Of course, it'd be much nicer to formalize this in Kurtosis. Replace your `main.star` with the following: + +```python +data_package_module = import_module("github.com/kurtosis-tech/awesome-kurtosis/data-package/main.star") + +POSTGRES_PORT_ID = "postgres" +POSTGRES_DB = "app_db" +POSTGRES_USER = "app_user" +POSTGRES_PASSWORD = "password" + +SEED_DATA_DIRPATH = "/seed-data" + +POSTGREST_PORT_ID = "http" + +def run(plan, args): + # Make data available for use in Kurtosis + data_package_module_result = data_package_module.run(plan, struct()) + + # Add a Postgres server + postgres = plan.add_service( + service_name = "postgres", + config = ServiceConfig( + image = "postgres:15.2-alpine", + ports = { + POSTGRES_PORT_ID: PortSpec(5432, application_protocol = "postgresql"), + }, + env_vars = { + "POSTGRES_DB": POSTGRES_DB, + "POSTGRES_USER": POSTGRES_USER, + "POSTGRES_PASSWORD": POSTGRES_PASSWORD, + }, + files = { + SEED_DATA_DIRPATH: data_package_module_result.files_artifact, + } + ), + ) + + # Wait for Postgres to become available + postgres_flags = ["-U", POSTGRES_USER,"-d", POSTGRES_DB] + plan.wait( + service_name = "postgres", + recipe = ExecRecipe(command = ["psql"] + postgres_flags + ["-c", "\\l"]), + field = "code", + assertion = "==", + target_value = 0, + timeout = "5s", + ) + + # Load the data into Postgres + plan.exec( + service_name = "postgres", + recipe = ExecRecipe(command = ["pg_restore"] + postgres_flags + [ + "--no-owner", + "--role=" + POSTGRES_USER, + SEED_DATA_DIRPATH + "/" + data_package_module_result.tar_filename, + ]), + ) + + # Add PostgREST + postgres_url = "postgresql://{}:{}@{}:{}/{}".format( + POSTGRES_USER, + POSTGRES_PASSWORD, + postgres.hostname, + postgres.ports[POSTGRES_PORT_ID].number, + POSTGRES_DB, + ) + api = plan.add_service( + service_name = "api", + config = ServiceConfig( + image = "postgrest/postgrest:v10.2.0.20230209", + env_vars = { + "PGRST_DB_URI": postgres_url, + "PGRST_DB_ANON_ROLE": POSTGRES_USER, + }, + ports = {POSTGREST_PORT_ID: PortSpec(3000, application_protocol = "http")}, + ) + ) + + # Wait for PostgREST to become available + plan.wait( + service_name = "api", + recipe = GetHttpRequestRecipe( + port_id = POSTGREST_PORT_ID, + endpoint = "/actor?limit=5", + ), + field = "code", + assertion = "==", + target_value = 200, + timeout = "5s", + ) + + # Insert data + if args != None: + insert_data(plan, args) + +def insert_data(plan, data): + plan.request( + service_name = "api", + recipe = PostHttpRequestRecipe( + port_id = POSTGREST_PORT_ID, + endpoint = "/actor", + content_type = "application/json", + body = json.encode(data), + ) + ) +``` + +Now clean and run, only this time with extra args to `kurtosis run`: + +```bash +kurtosis clean -a && kurtosis run --enclave quickstart . '[{"first_name":"Kevin", "last_name": "Bacon"}, {"first_name":"Steve", "last_name":"Buscemi"}]' +``` + +Using the new `http` URL on the `api` service in the output, query for the rows you just added (replacing `$YOUR_PORT` with your correct PostgREST `http` port number)... + +```bash +curl -XGET "http://127.0.0.1:$YOUR_PORT/actor?or=(last_name.eq.Buscemi,last_name.eq.Bacon)" +``` + +...to yield: + +```text +[{"actor_id":201,"first_name":"Kevin","last_name":"Bacon","last_update":"2023-03-15T02:29:53.454697"}, + {"actor_id":202,"first_name":"Steve","last_name":"Buscemi","last_update":"2023-03-15T02:29:53.454697"}] +``` + +### Review +How did this work? + +Mechanically, we first create a JSON string of data using Starlark's `json.encode` builtin. Then we use [the `request` Starlark instruction][request-reference] to shove the string at PostgREST, which writes it to the database: + +```python +plan.request( + service_name = "api", + recipe = PostHttpRequestRecipe( + port_id = POSTGREST_PORT_ID, + endpoint = "/actor", + content_type = "application/json", + body = json.encode(data), + ) +) +``` + +At a higher level, Kurtosis automatically deserialized the `[{"first_name":"Kevin", "last_name": "Bacon"}, {"first_name":"Steve", "last_name":"Buscemi"}]` string passed as a parameter to `kurtosis run`, and put the deserialized object in the `args` parameter to the `run` function in `main.star`: + +```python +def run(plan, args): +``` + + + + + +Conclusion +---------- +And that's it - you've written your very first distributed application in Kurtosis! + +Let's review. In this tutorial you have: + +- Started a Postgres database +- Seeded it by importing a third-party Starlark package +- Added an API server +- Inserted & queried data via the API +- Parameterized data insertion + +Along the way you've learned about several Kurtosis concepts: + +- [The CLI][cli-reference] +- [Enclaves][enclaves-explanation] +- [Starlark][starlark-explanation] +- [Multi-phase runs][multi-phase-runs-reference] +- [The plan][plan-reference] +- [Files artifacts][files-artifacts-reference] +- [Kurtosis packages][packages-reference] +- [Future references][future-references-reference] + +But this was still just the intro to Kurtosis. To see examples that you can easily modify to be relevant to you, [check out our `awesome-kurtosis` repo][awesome-kurtosis-repo]. To explore real-scale Kurtosis packages delivering value, see [the Ethereum package][ethereum-package], [Waku package][waku-package], or [NEAR package][near-package]. + +And now that you've reached the end, we'd love to hear from you - what went well for you, and what didn't? You can file issues and feature requests on Github... + +```bash +kurtosis feedback --github +``` + +...or you can email us via the CLI... + +```bash +kurtosis feedback --email +``` + +...and you can even schedule a personal session with [our cofounder Kevin][kevin-linked] via: + +```bash +kurtosis feedback --calendly +``` + +We use all feedback to fuel product development, so please don't hesitate to get in touch! + +Finally, if liked what you saw and want to engage with us, you can: + +- [Star us on Github](https://github.com/kurtosis-tech/kurtosis) (this helps a lot!) +- [Join our Discord](https://discord.com/channels/783719264308953108/783719264308953111) (also available with the `kurtosis discord` CLI command) +- [Reach out to us on Twitter](https://twitter.com/KurtosisTech) + +Or you can simply dive deeper into the docs: + +- [Read about the architecture][architecture-explanation] +- [Explore the full catalog of Starlark commands][starlark-instructions-reference] +- [Explore the various CLI commands][cli-reference] +- Explore [Kurtosis-provided packages being used in production][kurtosis-managed-packages] +- [Search GitHub for Kurtosis packages in the wild][wild-kurtosis-packages] + + + + +[installing-kurtosis-guide]: ./guides/installing-the-cli.md +[upgrading-kurtosis-guide]: ./guides/upgrading-the-cli.md + + +[architecture-explanation]: ./explanations/architecture.md +[enclaves-explanation]: ./explanations/architecture.md#enclaves +[services-explanation]: ./explanations/architecture.md#services +[starlark-explanation]: ./explanations/starlark.md +[reusable-environment-definitions-explanation]: ./explanations/reusable-environment-definitions.md +[what-is-kurtosis-explanation]: ./explanations/what-is-kurtosis.md +[how-do-imports-work-explanation]: ./explanations/how-do-kurtosis-imports-work.md +[why-multi-phase-runs-explanation]: ./explanations/why-multi-phase-runs.md + + + +[cli-reference]: ./reference/cli/cli.md +[kurtosis-run-reference]: ./reference/cli/run-starlark.md +[kurtosis-clean-reference]: ./reference/cli/clean.md +[kurtosis-clean-reference]: ./reference/cli/clean.md +[kurtosis-enclave-inspect-reference]: ./reference/cli/enclave-inspect.md +[kurtosis-files-upload-reference]: ./reference/cli/files-upload.md +[kurtosis-feedback-reference]: ./reference/cli/feedback.md +[kurtosis-twitter]: ./reference/cli/twitter.md + + +[starlark-instructions-reference]: ./reference/starlark-instructions.md +[upload-files-reference]: ./reference/starlark-instructions.md#upload_files +[request-reference]: ./reference/starlark-instructions.md#request + + +[multi-phase-runs-reference]: ./reference/multi-phase-runs.md +[kurtosis-yml-reference]: ./reference/kurtosis-yml.md +[packages-reference]: ./reference/packages.md +[runnable-packages-reference]: ./reference/packages.md#runnable-packages +[locators-reference]: ./reference/locators.md +[plan-reference]: ./reference/plan.md +[future-references-reference]: ./reference/future-references.md +[files-artifacts-reference]: ./reference/files-artifacts.md + + + +[awesome-kurtosis-repo]: https://github.com/kurtosis-tech/awesome-kurtosis +[data-package-example]: https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/data-package +[data-package-example-main.star]: https://github.com/kurtosis-tech/awesome-kurtosis/blob/main/data-package/main.star +[data-package-example-seed-tar]: https://github.com/kurtosis-tech/awesome-kurtosis/blob/main/data-package/dvd-rental-data.tar + + +[homepage]: https://kurtosis.com +[kevin-linked]: https://www.linkedin.com/in/kevintoday/ +[kurtosis-managed-packages]: https://github.com/kurtosis-tech?q=in%3Aname+package&type=all&language=&sort= +[wild-kurtosis-packages]: https://github.com/search?q=filename%3Akurtosis.yml&type=code +[bazel-github]: https://github.com/bazelbuild/bazel/ +[starlark-github-repo]: https://github.com/bazelbuild/starlark +[postgrest]: https://postgrest.org/en/stable/ +[ethereum-package]: https://github.com/kurtosis-tech/eth2-package +[waku-package]: https://github.com/logos-co/wakurtosis +[near-package]: https://github.com/kurtosis-tech/near-package +[iterm]: https://iterm2.com/ diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/analytics-disable.md b/docs/versioned_docs/version-0.70.6/reference/cli/analytics-disable.md new file mode 100644 index 0000000000..60760eb04c --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/analytics-disable.md @@ -0,0 +1,13 @@ +--- +title: analytics disable +sidebar_label: analytics disable +slug: /analytics-disable +--- + +Kurtosis has the ability to send product analytics metrics, enabling us to understand our users better so that we can improve the product over time. While this capability is enabled by default, you may choose to opt-out by running the following command: + +```bash +kurtosis analytics disable +``` + +This data is private, anonymized, obfuscated, and can be opted-out from. To learn more, we encourage you to read more about our [metrics philosophy](../../explanations/metrics-philosophy.md). \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/analytics-enable.md b/docs/versioned_docs/version-0.70.6/reference/cli/analytics-enable.md new file mode 100644 index 0000000000..45ae6788ac --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/analytics-enable.md @@ -0,0 +1,15 @@ +--- +title: analytics enable +sidebar_label: analytics enable +slug: /analytics-enable +--- + +Kurtosis has the ability to send product analytics metrics, enabling us to understand our users better so that we can improve the product over time. This capability is enabled by default. + +However, if you previously disabled the sending of product analytics metrics using `[kurtosis analytics disable](./analytics-disable.md)` and wish to re-enable this capability, run: + +```bash +kurtosis analytics enable +``` + +This data is private, anonymized, obfuscated, and can be opted-out from. To learn more, we encourage you to read more about our [metrics philosophy](../../explanations/metrics-philosophy.md). \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/analytics-id.md b/docs/versioned_docs/version-0.70.6/reference/cli/analytics-id.md new file mode 100644 index 0000000000..8d3e6b9ecd --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/analytics-id.md @@ -0,0 +1,15 @@ +--- +title: analytics id +sidebar_label: analytics id +slug: /analytics-id +--- + +In addition to log outputs and screenshots, [product analytics metrics](../../explanations/metrics-philosophy.md) may be useful for our team when debugging issues and shipping fixes for bugs. + +If you so choose, you may share with us your metrics user ID when letting us know about issues or bugs (in our [Github](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) or on [Discord](https://discord.gg/rjkj8m5C)). Doing helps us debug issues, ship fixes quicker, and ultimately improve Kurtosis over time. + +To print your metrics user ID, simply run: + +```bash +kurtosis analytics id +``` diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/clean.md b/docs/versioned_docs/version-0.70.6/reference/cli/clean.md new file mode 100644 index 0000000000..b38a4e207a --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/clean.md @@ -0,0 +1,15 @@ +--- +title: clean +sidebar_label: clean +slug: /clean +--- + +Kurtosis defaults to leaving enclave artifacts (containers, volumes, etc.) around so that you can refer back them for debugging. To clean up artifacts from stopped enclaves, run: + +```bash +kurtosis clean +``` + +To remove artifacts from _all_ enclaves (including running ones), add the `-a`/`--all` flag. + +NOTE: This will not stop the Kurtosis engine itself! To do so, use the [engine stop](./engine-stop.md) command. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/cli.md b/docs/versioned_docs/version-0.70.6/reference/cli/cli.md new file mode 100644 index 0000000000..7793394467 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/cli.md @@ -0,0 +1,38 @@ +--- +title: Getting Started +sidebar_label: CLI +slug: /cli +sidebar_position: 1 +--- + +This section will go through the most common Kurtosis CLI commands and some useful tips on getting started. If you have not already done so, the CLI can be installed by following the instructions [here][installing-the-cli]. + +:::tip +The `kurtosis` command, and all of its subcommands, will print helptext when passed the `-h` or `--help` flag. You can use this at any time to see information on the command you're trying to run. For example: +``` +kurtosis service -h +``` +::: + +:::tip +Kurtosis supports command-line completion; we recommend [installing it][adding-command-line-completion] for the best experience. +::: + +### Configuration file path +To locate where the Kurtosis configuration file is on your machine, simply use: + +```bash +kurtosis config path +``` +to print out the file path of the `kurtosis-config.yml` file. + +### Get the CLI version +The CLI version along with the currently running engine if any; can be printed with the following: + +``` +kurtosis version +``` + + +[adding-command-line-completion]: ../../guides/adding-command-line-completion.md +[installing-the-cli]: ../../guides/installing-the-cli.md diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/completion.md b/docs/versioned_docs/version-0.70.6/reference/cli/completion.md new file mode 100644 index 0000000000..deeb15ae45 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/completion.md @@ -0,0 +1,20 @@ +--- +title: completion +sidebar_label: completion +slug: /completion +--- + +Scripts used to create command-line completion for `bash`, `fish`, `powershell`, and `zsh` can be printed using: + +```bash +kurtosis completion [command] +``` + +The available commands are as follows: + +* `bash`: Generates the autocompletion script for bash +* `fish`: Generates the autocompletion script for fish +* `powershell`: Generates the autocompletion script for powershell +* `zsh`: Generates the autocompletion script for zsh + +Instructions for how to install command-line completion on your shell can be found [here](../../guides/adding-command-line-completion.md) in our Guides section. diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/discord.md b/docs/versioned_docs/version-0.70.6/reference/cli/discord.md new file mode 100644 index 0000000000..291f08cb4b --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/discord.md @@ -0,0 +1,11 @@ +--- +title: discord +sidebar_label: discord +slug: /discord +--- + +The following command can be used to open our Discord server from the CLI where you can join our Discord to ask questions, chat with our team, and meet the community: + +```bash +kurtosis discord +``` \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/docs.md b/docs/versioned_docs/version-0.70.6/reference/cli/docs.md new file mode 100644 index 0000000000..7a186b3474 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/docs.md @@ -0,0 +1,13 @@ +--- +title: docs +sidebar_label: docs +slug: /docs +--- + +To open our documentation in the browser from the CLI, run: + +```bash +kurtosis docs +``` + +where you can learn more about Kurtosis' architecture, our SDK, and much more. diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/dump.md b/docs/versioned_docs/version-0.70.6/reference/cli/dump.md new file mode 100644 index 0000000000..34152ce227 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/dump.md @@ -0,0 +1,17 @@ +--- +title: dump +sidebar_label: dump +slug: /dump +--- + +You might need to store the entire state of Kurtosis to disk at some point. You may want to have a log package if your CI fails, or you want to send debugging information to [the author of a Kurtosis package][packages-reference]. Whatever the case may be, you can run: + +```bash +kurtosis dump $OUTPUT_DIRECTORY +``` +You will get the container logs & configuration in the output directory for further analysis & sharing. This would contain all engines & enclaves. + +If you don't specify the `$OUTPUT_DIRECTORY` Kurtosis will dump it to a directory with the name `kurtosis-dump`. + + +[packages-reference]: ../packages.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/enclave-add.md b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-add.md new file mode 100644 index 0000000000..9596188b2b --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-add.md @@ -0,0 +1,17 @@ +--- +title: enclave add +sidebar_label: enclave add +slug: /enclave-add +--- + +Your distributed applications run in [enclaves][enclaves-explanation]. They are isolated from each other, to ensure they don't interfere with each other. To create a new, empty enclave, simply run: + +```bash +kurtosis enclave add +``` + +To create enclaves that support [subnetworks][subnetworks] use the `--with-subnetworks` flag. + + +[enclaves-explanation]: ../../explanations/architecture.md#enclaves +[subnetworks]: ../../reference/subnetworks.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/enclave-dump.md b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-dump.md new file mode 100644 index 0000000000..2f125933e6 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-dump.md @@ -0,0 +1,20 @@ +--- +title: enclave dump +sidebar_label: enclave dump +slug: /enclave-dump +--- + +You will likely need to store enclave logs to disk at some point. You may want to have a log package if your CI fails, or you want to send debugging information to [the author of a Kurtosis package][packages-reference]. Whatever the case may be, you can run: + +```bash +kurtosis enclave dump $THE_ENCLAVE_IDENTIFIER $OUTPUT_DIRECTORY +``` +where the `$THE_ENCLAVE_IDENTIFIER` is the [resource identifier](../resource-identifier.md) for an enclave. + +You will get the container logs & configuration in the output directory for further analysis & sharing. + +If you don't specify the `$OUTPUT_DIRECTORY` Kurtosis will dump it to a directory with a name following the `ENCLAVE_NAME--ENCLAVE_UUID` scheme in the +current working directory. + + +[packages-reference]: ../packages.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/enclave-inspect.md b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-inspect.md new file mode 100644 index 0000000000..8724b8d430 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-inspect.md @@ -0,0 +1,23 @@ +--- +title: enclave inspect +sidebar_label: enclave inspect +slug: /enclave-inspect +--- + +To view detailed information about a given enclave, including its status and contents, run: + +```bash +kurtosis enclave inspect $THE_ENCLAVE_IDENTIFIER +``` + +where `$THE_ENCLAVE_IDENTIFIER` is the [resource identifier](../resource-identifier.md) for the enclave. + +Running the above command will print detailed information about: + +- The enclave's status (running or stopped) +- The services inside the enclave (if any), their status, and the information for accessing those services' ports from your local machine +- Any files artifacts registered within the specified enclave + +By default, UUIDs are shortened. To view the full UUIDs of your resources, add the following flag: +* `--full-uuids` + diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/enclave-ls.md b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-ls.md new file mode 100644 index 0000000000..0cd49f5d81 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-ls.md @@ -0,0 +1,13 @@ +--- +title: enclave ls +sidebar_label: enclave ls +slug: /enclave-ls +--- + +To print all enclaves (both stopped and running) inside of your Kurtosis engine, use: + +```bash +kurtosis enclave ls +``` + +The enclave UUIDs and names that are printed will be used in enclave manipulation commands and are refered to as [resource identifiers](../resource-identifier.md). \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/enclave-rm.md b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-rm.md new file mode 100644 index 0000000000..635e01fcf8 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-rm.md @@ -0,0 +1,14 @@ +--- +title: enclave rm +sidebar_label: enclave rm +slug: /enclave-rm +--- + +To remove an enclave and all resources associated with that particular enclave, use: + +```bash +kurtosis enclave rm $THE_ENCLAVE_IDENTIFIER +``` +where `$THE_ENCLAVE_IDENTIFIER` is the enclave [identifier](../resource-identifier.md). + +Note that this command will only remove stopped enclaves. To destroy a running enclave, pass the `-f`/`--force` flag. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/enclave-stop.md b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-stop.md new file mode 100644 index 0000000000..94c6c97ebb --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/enclave-stop.md @@ -0,0 +1,16 @@ +--- +title: enclave stop +sidebar_label: enclave stop +slug: /enclave-stop +--- + +To stop a particular enclave, use: + +```bash +kurtosis enclave stop $THE_ENCLAVE_IDENTIFIER +``` +where `$THE_ENCLAVE_IDENTIFIER` is the enclave [identifier](../resource-identifier.md). + +:::caution +Enclaves that have been stopped cannot currently be restarted. The Kurtosis team is actively working on enabling this functionality. +::: diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/engine-logs.md b/docs/versioned_docs/version-0.70.6/reference/cli/engine-logs.md new file mode 100644 index 0000000000..1572c2a480 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/engine-logs.md @@ -0,0 +1,14 @@ +--- +title: engine logs +sidebar_label: engine logs +slug: /engine-logs +--- + +To get logs for all existing engines, use: + +```bash +kurtosis engine logs $OUTPUT_DIRECTORY +``` + +This will dump all the logs of the container to the directory specified by `$OUTPUT_DIRECTORY`. If it isn't `$OUTPUT_DIRECTORY` isn't specified +Kurtosis will default to writing the logs in a folder called `kurtosis-engine-logs` diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/engine-restart.md b/docs/versioned_docs/version-0.70.6/reference/cli/engine-restart.md new file mode 100644 index 0000000000..5d2c0e6879 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/engine-restart.md @@ -0,0 +1,11 @@ +--- +title: engine restart +sidebar_label: engine restart +slug: /engine-restart +--- + +The CLI interacts with the Kurtosis engine, which is a very lightweight container. The CLI will start the engine container automatically for you and you should never need to start it manually, but you might need to restart the engine after a CLI upgrade. To do so, run: + +```bash +kurtosis engine restart +``` \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/engine-start.md b/docs/versioned_docs/version-0.70.6/reference/cli/engine-start.md new file mode 100644 index 0000000000..6d4c4d1eb0 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/engine-start.md @@ -0,0 +1,16 @@ +--- +title: engine start +sidebar_label: engine start +slug: /engine-start +--- + +The Kurtosis engine starts automatically when you run any command that interacts with the engine, such as [`kurtosis enclave add`](./enclave-add.md), but there may be times where the engine has been stopped and you may need to start it again (e.g. starting the engine on a specific version). To do so, run: + +```bash +kurtosis engine start +``` +This command will do nothing if the Kurtosis engine is already running. + +You may optionally pass in the following flags with this command: +* `--log-level`: The level that the started engine should log at. Options include: `panic`, `fatal`, `error`, `warning`, `info`, `debug`, or `trace`. The engine logs at the `info` level by default. +* `--version`: The version (Docker tag) of the Kurtosis engine that should be started. If not set, the engine will start up with the default version. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/engine-status.md b/docs/versioned_docs/version-0.70.6/reference/cli/engine-status.md new file mode 100644 index 0000000000..537660351a --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/engine-status.md @@ -0,0 +1,11 @@ +--- +title: engine status +sidebar_label: engine status +slug: /engine-status +--- + +The engine's version and status can be printed with: + +```bash +kurtosis engine status +``` \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/engine-stop.md b/docs/versioned_docs/version-0.70.6/reference/cli/engine-stop.md new file mode 100644 index 0000000000..80a222e0c7 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/engine-stop.md @@ -0,0 +1,13 @@ +--- +title: engine stop +sidebar_label: engine stop +slug: /engine-stop +--- + +To stop the engine, run: + +```bash +kurtosis engine stop +``` + +Note that this will do nothing if there is no engine running. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/feedback.md b/docs/versioned_docs/version-0.70.6/reference/cli/feedback.md new file mode 100644 index 0000000000..c3a1cf28e5 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/feedback.md @@ -0,0 +1,48 @@ +--- +title: feedback +sidebar_label: feedback +slug: /feedback +--- + +Your feedback is valuable and helps us improve Kurtosis. We thank you in advance for taking the time to share your suggestions and concerns with us. + +To send our team feedback over email straight from the CLI, simply run: +```bash +kurtosis feedback "$YOUR_FEEDBACK" +``` +where `$YOUR_FEEDBACK` is the feedback you would like to send to us. For example, `$YOUR_FEEDBACK` could be: "_I enjoy the enclave names_". + +Running the above command will open a draft email using your default email client with the `TO:` line pre-filled with our feedback email list (feedback@kurtosistech.com) and the body of the message pre-filled with `$YOUR_FEEDBACK` (that you entered in the command line). + +To quickly see all the ways you can get in touch with us, simply run: +```bash +kurtosis feedback +``` + +which will return: +- The link to our [Github](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) for filing bug reports and feature requests as Github Issues. +- Our [feedback email address](mailto:feedback@kurtosistech.com) for sending us suggestions, comments, or questions about Kurtosis via email. +- A [Calendly link](https://calendly.com/d/zgt-f2c-66p/kurtosis-onboarding) to schedule a dedicated 1:1 onboarding session with us to help you get started. + +##### Using `kurtosis feedback` + +The `kurtosis feedback` command can accept both an argument and various flags. To send our team feedback over Github straight from the CLI, simply pass in your feedback as an argument to the command like so: +```bash +kurtosis feedback [flags] ["YOUR_FEEDBACK"] +``` +where `YOUR_FEEDBACK` is the feedback you would like to send to us. + +Running just `kurtosis feedback "my feedback"` (with no flags) will open the new issue creation page on [our Github](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) where you can can select the issue type and have the description field pre-filled with `my feedback`. + +Below are a collection of valid flags you may use: +- The `--github` flag can be used to open the Issue creation page in our Github where you can select the Issue template you wish to use for your feedback. The `"$YOUR_FEEDBACK"` arg will be pre-populated in the description of whichever Issue template you select. +- The `--email` flag opens a draft email to feedback@kurtosistech.com, via your default mail client, that has the body of the email pre-filled with whatever you entered in the `"$YOUR_FEEDBACK"` arg. This is the default behavior when no flag is set. +- The `--calendly` flag can be used to open our [Calendly link](https://calendly.com/d/zgt-f2c-66p/kurtosis-onboarding) to schedule time with our team to help you get started, address feedback, and answer any questions you may have. +Additionally, the flags below can be used with `--github` and `--email` to specify the *type* of feedback you wish to provide: +- The `--bug` flag can be used when you wish to submit a bug report to us. When this `--bug` flag is set alongside the `--github` flag, the CLI will take you directly to the [bug report issue creation page](https://github.com/kurtosis-tech/kurtosis/issues/new?assignees=&labels=bug&template=bug-report.yml&title=%5Bbug%5D%3A+) in our Github. When this `--bug` flag is set alongside the `--email` flag, the CLI will open an email draft with the subject pre-filled with: `[BUG]`, which will help our team triage and prioritize your report. +- The `--feature` flag can be used when you wish to submit a feature request to us. When this `--feature` flag is set alongside the `--github` flag, the CLI will take you directly to the [feature request issue creation page](https://github.com/kurtosis-tech/kurtosis/issues/new?assignees=&labels=feature+request&template=feature-request.yml&title=%5BFR%5D%3A+) in our Github. When this `--feature` flag is set alongside the `--email` flag, the CLI will open an email draft with the subject pre-filled with: `[FEATURE_REQUEST]`, which will help our team triage and prioritize your request. +- The `--docs` flag can be used when you wish to flag an issue with our documentation. When this `--docs` flag is set alongside the `--github` flag, the CLI will take you directly to the [docs issue creation page](https://github.com/kurtosis-tech/kurtosis/issues/new?assignees=leeederek&labels=docs&template=docs-issue.yml&title=%5BDocs%5D%3A+) in our Github. When this `--docs` flag is set alongside the `--email` flag, the CLI will open an email draft with the subject pre-filled with: `[DOCS]`, which will help our team triage and prioritize the issue. + +:::tip +To join our Discord community, use the [`kurtosis discord`](./discord.md) CLI command. +::: diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/files-download.md b/docs/versioned_docs/version-0.70.6/reference/cli/files-download.md new file mode 100644 index 0000000000..64ae3025b4 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/files-download.md @@ -0,0 +1,16 @@ +--- +title: files download +sidebar_label: files download +slug: /files-download +--- + +To download a [files artifact](../files-artifacts.md) using a resource identifier (e.g. name, UUID, shortened UUID) from an enclave to the host machine, use: + +```bash +kurtosis files download $THE_ENCLAVE_IDENTIFIER $THE_ARTIFACT_IDENTIFIER $FILE_DESTINATION_PATH +``` +where `$THE_ENCLAVE_IDENTIFIER` and the `$THE_ARTIFACT_IDENTIFIER` are [resource identifiers](../resource-identifier.md) for the enclave and file artifact, respectively. + +:::tip +The file downloaded will be extracted by default. If you would prefer the file not to be extracted upon download, pass in the `--no-extract` flag. +::: \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/files-rendertemplate.md b/docs/versioned_docs/version-0.70.6/reference/cli/files-rendertemplate.md new file mode 100644 index 0000000000..64a291b55c --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/files-rendertemplate.md @@ -0,0 +1,14 @@ +--- +title: files rendertemplate +sidebar_label: files rendertemplate +slug: /files-rendertemplate +--- +To render a [Golang template](https://pkg.go.dev/text/template) for customizing the output of a service within an enclave, use the following command: + +```bash +kurtosis files rendertemplate $THE_ENCLAVE_IDENTIFIER $TEMPLATE_FILEPATH $DATA_JSON_FILEPATH $DESTINATION_RELATIVE_FILEPATH +``` + +where `$THE_ENCLAVE_IDENTIFIER` is the [resource identifier](../resource-identifier.md) for the enclave. + +The name of the rendered [files artifact](../files-artifacts.md) is auto-generated by default. Pass in the `--name` flag to assign a string to the produced artifact. diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/files-storeservice.md b/docs/versioned_docs/version-0.70.6/reference/cli/files-storeservice.md new file mode 100644 index 0000000000..7d933a493b --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/files-storeservice.md @@ -0,0 +1,13 @@ +--- +title: files storeservice +sidebar_label: files storeservice +slug: /files-storeservice +--- + +To instruct Kurtosis to copy a file or folder from a given absolute filepath in a given service and store it in the enclave for later use (e.g. with [`service add`](./service-add.md)), use: + +```bash +kurtosis files storeservice $THE_ENCLAVE_IDENTIFIER $THE_SERVICE_IDENTIFIER $ABSOLUTE_SOURCE_FILEPATH +``` + +where `$THE_ENCLAVE_IDENTIFIER` and the `$THE_SERVICE_IDENTIFIER` are [resource identifiers](../resource-identifier.md) for the enclave and service, respectively. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/files-storeweb.md b/docs/versioned_docs/version-0.70.6/reference/cli/files-storeweb.md new file mode 100644 index 0000000000..81622a5d9d --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/files-storeweb.md @@ -0,0 +1,13 @@ +--- +title: files storeweb +sidebar_label: files storeweb +slug: /files-storeweb +--- + +To download an archive file from the given URL and store it in the enclave for later use (e.g. with [`service add`](./service-add.md)), use: + +```bash +kurtosis files storeweb $THE_ENCLAVE_IDENTIFIER $URL +``` + +where `$THE_ENCLAVE_IDENTIFIER` is the [resource identifier](../resource-identifier.md) for the enclave. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/files-upload.md b/docs/versioned_docs/version-0.70.6/reference/cli/files-upload.md new file mode 100644 index 0000000000..14f4345728 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/files-upload.md @@ -0,0 +1,14 @@ +--- +title: files upload +sidebar_label: files upload +slug: /files-upload +--- + +Files can be stored as a [files artifact][files-artifacts] inside an enclave by uploading them: + +```bash +kurtosis files upload $PATH_TO_FILES +``` + + +[files-artifacts]: ../files-artifacts.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/run-starlark.md b/docs/versioned_docs/version-0.70.6/reference/cli/run-starlark.md new file mode 100644 index 0000000000..31ba0688d5 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/run-starlark.md @@ -0,0 +1,50 @@ +--- +title: run +sidebar_label: run +slug: /run-starlark +--- + +Kurtosis can be used to run a Starlark script or a [runnable package](../packages.md) in an enclave. + +A single Starlark script can be ran with: + +```bash +kurtosis run script.star +``` + +Adding the `--dry-run` flag will print the changes without executing them. + +A [Kurtosis package](../packages.md) on your local machine can be run with: + +```bash +kurtosis run /path/to/package/on/your/machine +``` + +A [runnable Kurtosis package](../packages.md) published to GitHub can be run like so: + +```bash +kurtosis run github.com/package-author/package-repo +``` + +:::tip +If you want to run a non-main branch, tag or commit use the following syntax +`kurtosis run github.com/package-author/package-repo@tag-branch-commit` +::: + +Arguments can be provided to a Kurtosis package (either local or from GitHub) by passing a JSON-serialized object with args argument, which is the second positional argument you pass to `kurtosis run` like: + +```bash +# Local package +kurtosis run /path/to/package/on/your/machine '{"company":"Kurtosis"}' + +# GitHub package +kurtosis run github.com/package-author/package-repo '{"company":"Kurtosis"}' +``` + +This command has options available to customize its execution: + +1. The `--dry-run` flag can be used to print the changes proposed by the script without executing them +1. The `--parallelism` flag can be used to specify to what degree of parallelism certain commands can be run. For example: If the script contains [`add_services`](../starlark-instructions.md#add_service) and is run with `--parallelism 100`, up to 100 services will be run at one time. +1. The `--enclave-id` flag can be used to instruct Kurtosis to run the script inside the specified enclave or create a new enclave (with the given enclave [identifier](../resource-identifier.md)) if one does not exist. If this flag is not used, Kurtosis will create a new enclave with an auto-generated name, and run the script or package inside it. +1. The `--with-subnetworks` flag can be used to enable [subnetwork capabilties](../subnetworks.md) within the specified enclave that the script or package is instructed to run within. This flag is false by default. +1. The `--verbosity` flag can be used to set the verbosity of the command output. The options include `BRIEF`, `DETAILED`, or `EXECUTABLE`. If unset, this flag defaults to `BRIEF` for a concise and explicit output. Use `DETAILED` to display the exhaustive list of arguments for each command. Meanwhile, `EXECUTABLE` will generate executable Starlark instructions. diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/service-add.md b/docs/versioned_docs/version-0.70.6/reference/cli/service-add.md new file mode 100644 index 0000000000..66c2bfbc96 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/service-add.md @@ -0,0 +1,25 @@ +--- +title: service add +sidebar_label: service add +slug: /service-add +--- + +To add a service to an enclave, run: + +```bash +kurtosis service add $THE_ENCLAVE_IDENTIFIER $THE_SERVICE_IDENTIFIER $CONTAINER_IMAGE +``` + +where `$THE_ENCLAVE_IDENTIFIER` and the `$THE_SERVICE_IDENTIFIER` are [resource identifiers](../resource-identifier.md) for the enclave and service, respectively. + +Much like `docker run`, this command has multiple options available to customize the service that's started: + +1. The `--entrypoint` flag can be passed in to override the binary the service runs +1. The `--env` flag can be used to specify a set of environment variables that should be set when running the service +1. The `--ports` flag can be used to set the ports that the service will listen on + +To override the service's CMD, add a `--` after the image name and then pass in your CMD args like so: + +```bash +kurtosis service add --entrypoint sh my-enclave test-service alpine -- -c "echo 'Hello world'" +``` \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/service-delete.md b/docs/versioned_docs/version-0.70.6/reference/cli/service-delete.md new file mode 100644 index 0000000000..9e5e6311cf --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/service-delete.md @@ -0,0 +1,15 @@ +--- +title: service delete +sidebar_label: service delete +slug: /service-delete +--- + +Services can be deleted from an enclave like so: + +```bash +kurtosis service rm $THE_ENCLAVE_IDENTIFIER $THE_SERVICE_IDENTIFIER +``` + +where `$THE_ENCLAVE_IDENTIFIER` and the `$THE_SERVICE_IDENTIFIER` are [resource identifiers](../resource-identifier.md) for the enclave and service, respectively. + +**NOTE:** To avoid destroying debugging information, Kurtosis will leave removed services inside the Docker engine. They will be stopped and won't show up in the list of active services in the enclave, but you'll still be able to access them (e.g. using `service logs`) by their service GUID (available via `enclave inspect`). \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/service-logs.md b/docs/versioned_docs/version-0.70.6/reference/cli/service-logs.md new file mode 100644 index 0000000000..6511f89c2d --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/service-logs.md @@ -0,0 +1,21 @@ +--- +title: service logs +sidebar_label: service logs +slug: /service-logs +--- + +To print the logs for a service, run: + +```bash +kurtosis service logs $THE_ENCLAVE_IDENTIFIER $THE_SERVICE_IDENTIFIER +``` + +where `$THE_ENCLAVE_IDENTIFIER` and the `$THE_SERVICE_IDENTIFIER` are [resource identifiers](../resource-identifier.md) for the enclave and service, respectively. The service identifier (name or UUID) is printed upon inspecting an enclave. + +The following optional arguments can be used: +1. `-f`, `-follow` can be added to continue following the logs, similar to `tail -f`. +1. `--match=text` can be used for filtering the log lines containing the text. +1. `--regex-match="regex"` can be used for filtering the log lines containing the regex. This filter will also work for text but will have degraded performance. +1. `-v`, `--invert-match` can be used to invert the filter condition specified by either `--match` or `--regex-match`. Log lines NOT containing the match will be returned. + +Important: `--match` and `--regex-match` flags cannot be used at the same time. You should either use one or the other. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/service-shell.md b/docs/versioned_docs/version-0.70.6/reference/cli/service-shell.md new file mode 100644 index 0000000000..d4d4637da1 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/service-shell.md @@ -0,0 +1,13 @@ +--- +title: service shell +sidebar_label: service shell +slug: /service-shell +--- + +To get access to a shell on a given service container, run: + +```bash +kurtosis service shell $THE_ENCLAVE_IDENTIFIER $THE_SERVICE_IDENTIFIER +``` + +where `$THE_ENCLAVE_IDENTIFIER` and the `$THE_SERVICE_IDENTIFIER` are [resource identifiers](../resource-identifier.md) for the enclave and service, respectively. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/cli/twitter.md b/docs/versioned_docs/version-0.70.6/reference/cli/twitter.md new file mode 100644 index 0000000000..8fab8a256a --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/cli/twitter.md @@ -0,0 +1,11 @@ +--- +title: twitter +sidebar_label: twitter +slug: /twitter +--- + +The following command can be used to open a link to our [Twitter account](https://twitter.com/KurtosisTech) from the CLI where you can follow along for announcements and exciting updates. + +```bash +kurtosis twitter +``` diff --git a/docs/versioned_docs/version-0.70.6/reference/files-artifacts.md b/docs/versioned_docs/version-0.70.6/reference/files-artifacts.md new file mode 100644 index 0000000000..46037199f5 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/files-artifacts.md @@ -0,0 +1,26 @@ +--- +title: Files Artifacts +sidebar_label: Files Artifacts +--- + +Kurtosis enclaves can store files for later use. Files stored in a Kurtosis enclave are stored as compressed TGZ files. These TGZs are called "files artifacts". + +For example, a user can upload files on their machine to an enclave like so: + +```bash +kurtosis files upload $SOME_PATH +``` + +:::info +If `$SOME_PATH` is a file, that single file will be packaged inside the files artifact. If `$SOME_PATH` is a directory, all of the directory's contents will be packaged inside the files artifact. +::: + +Doing so will return a randomly-generated ID and name that can be used to reference the files artifact for later use. + +For example, the `--files` flag of `kurtosis service add` can be used to mount the contents of a files artifact at specified location. This command will mount the contents of files artifact `test-artifact` at the `/data` directory: + +```bash +kurtosis service add "some-enclave" "some-service-name" --files "/data:test-artifact" +``` + +The same files artifact can be reused many times because the contents of a files artifact is copied when it is used. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/future-references.md b/docs/versioned_docs/version-0.70.6/reference/future-references.md new file mode 100644 index 0000000000..9b4c6a62d3 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/future-references.md @@ -0,0 +1,48 @@ +--- +title: Future References +sidebar_label: Future References +--- + +Kurtosis uses [a multi-phase approach][multi-phase-runs-reference] when running [Starlark scripts][starlark-explanation]. + +For the user, the important thing to remember is that [any value returned by a Kurtosis Starlark instruction][starlark-instructions-reference] is not the actual value - it is a special string referencing the _future_ value that will exist during the Execution Phase. + +For example: + +```python +service = add_service( + "my-service", + config = struct( + image = "hello-world", + ) +) +print(service.ip_address) +``` + +does not in fact print the actual IP address of the service, because the service does not exist during the Interpretation Phase. Instead, `service.ip_address` is a string referencing the future value of the service's IP address: + +``` +{{kurtosis:my-service.ip_address}} +``` + +Anywhere this future reference string is used, Kurtosis will slot in the actual value during the Execution Phase. For example, when the `print` statement is executed during the Execution Phase, Kurtosis will replace the future reference with the actual value so that the service's actual IP address gets printed: + +``` +> print "{{kurtosis:my-service.ip_address}}" +172.19.10.3 +``` + +:::caution +The format of these future reference strings is undefined and subject to change; users should not construct them manually! +::: + +All values that are available exclusively during the Execution Phase will be handled in Starlark as future reference strings. This includes: + +- Service information +- Files artifact information +- Execution-time values (e.g. values returned by HTTP requests or `exec`ing a command on a container) + + +[multi-phase-runs-reference]: ./multi-phase-runs.md +[starlark-explanation]: ../explanations/starlark.md +[starlark-instructions-reference]: ./starlark-instructions.md diff --git a/docs/versioned_docs/version-0.70.6/reference/glossary.md b/docs/versioned_docs/version-0.70.6/reference/glossary.md new file mode 100644 index 0000000000..3dff8c1a42 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/glossary.md @@ -0,0 +1,35 @@ +--- +title: Glossary +sidebar_label: Glossary +--- + + + +### CLI +A command line interface, [installed by your favorite package manager](../guides/installing-the-cli.md), which wraps an instance of [the Kurtosis SDK][sdk-reference] to allow you to manipulate the contents of Kurtosis. + +### Enclave +An environment, isolated from other enclaves, in which distributed systems are launched and manipulated. + +### Engine +The Kurtosis engine which receives instructions via [the Kurtosis SDK][sdk-reference] (e.g. "launch this service in this enclave", "create a new enclave", "destroy this enclave", etc.). + +### Locator +A URL-like string for referencing resources. Also see [the extended documentation][locators]. + +### Package +A directory containing [a `kurtosis.yml` file][kurtosis-yml] and any additional modules and static files that the package needs. Also see [the extended documentation][packages]. + +### Starlark +[A minimal, Python-like language invented at Google](https://github.com/bazelbuild/starlark) for configuring their build tool, Bazel. + +### User Service +A container, launched inside an enclave upon a request to the Kurtosis engine, that is started from whatever image the user pleases. + + + + +[locators]: ./locators.md +[kurtosis-yml]: ./kurtosis-yml.md +[packages]: ./packages.md +[sdk-reference]: ./sdk.md diff --git a/docs/versioned_docs/version-0.70.6/reference/kurtosis-yml.md b/docs/versioned_docs/version-0.70.6/reference/kurtosis-yml.md new file mode 100644 index 0000000000..61a913cbc7 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/kurtosis-yml.md @@ -0,0 +1,37 @@ +--- +title: kurtosis.yml +sidebar_label: kurtosis.yml +--- + +:::info +The `kurtosis.yml` is part of the Kurtosis package system. To read about the package system in detail, [see here][how-do-kurtosis-imports-work-explanation]. +::: + +The `kurtosis.yml` file is a manifest file necessary to turn a directory into [a Kurtosis package][package]. This is the spec for the `kurtosis.yml`: + + + +```yaml +# The locator naming this package. +name: github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml +``` + +Example usage: + +if kurtosis.yml is in the repository root: +```yaml +name: github.com/author/package-repo +``` + +if kurtosis.yml is in a directory other than repository root: +```yaml +name: github.com/author/package-repo/path/to/directory-with-kurtosis.yml +``` + +:::info +The key take away is that `/path/to/directory-with-kurtosis.yml` only needs to be provided if `kurtosis.yml` is not present in the repository's root. +::: + + +[package]: ./packages.md +[how-do-kurtosis-imports-work-explanation]: ../explanations/how-do-kurtosis-imports-work.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/locators.md b/docs/versioned_docs/version-0.70.6/reference/locators.md new file mode 100644 index 0000000000..7aa9222292 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/locators.md @@ -0,0 +1,79 @@ +--- +title: Locators +sidebar_label: Locators +--- + +:::info +Locators are a part of the Kurtosis package system. To read about the package system in detail, [see here][how-do-kurtosis-imports-work-explanation]. +::: + +A locator is a URL-like string used to locate a resource inside [a Kurtosis package][packages]. For example, this locator: + +``` +github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml/some-file.star +``` + +references a file inside a GitHub repo called `package-repo`, owned by `package-author`, that lives at the path `/path/to/directory-with-kurtosis.yml/some-file.star` relative to the root of the repo. + + +Locators are used for identifying resources that will be used inside a Starlark script - namely by [`import_module`](./starlark-instructions.md#import_module) and [`read_file`](./starlark-instructions.md#read_file). + +:::caution +A GitHub URL is **not** a valid locator, because GitHub adds extra `/blob/main` paths to the URL that don't reflect the file's path in the repo. For example, a GitHub URL of: + +``` +https://github.com/kurtosis-tech/kurtosis/blob/main/starlark/test.star +``` + +would be the following as a Kurtosis locator (dropping the `https://` and `/blob/main` part): + +``` +github.com/kurtosis-tech/kurtosis/starlark/test.star +``` +::: + +:::info +Only locators pointing to public GitHub repositories are currently allowed. +::: + +Any Starlark script that wishes to use external resources must be +a part of a [Kurtosis package][packages]. + +All locators are absolute; "relative" locators do not exist. For a Starlark script to reference a local file (i.e. one that lives next to in the filesystem), the Starlark script must use the name of the package that it lives inside. + +For example, suppose we had a [Kurtosis package][packages] like so: + +``` +/ + package-repo + my-package + kurtosis.yml + main.star + helpers + random-script.star + not-a-package + random-script.star +``` + +with a `kurtosis.yml` file like so: + +```yaml +name: github.com/package-author/package-repo/my-package +``` + +The `main.star` file would import the `random-script.star` from the `helpers` subdirectory of `my-package` like so: + +```python +helpers = import_module("github.com/package-author/package-repo/my-package/helpers/random-script.star") +``` + +The import statement below will not succeed, this is because `main.star` cannot import from non-packages. +(see [how import works][how-do-kurtosis-imports-work-explanation] for more information) + +```python +helpers = import_module("github.com/package-author/package-repo/not-a-package/random-script.star") +``` + + +[packages]: ./packages.md +[how-do-kurtosis-imports-work-explanation]: ../explanations/how-do-kurtosis-imports-work.md diff --git a/docs/versioned_docs/version-0.70.6/reference/multi-phase-runs.md b/docs/versioned_docs/version-0.70.6/reference/multi-phase-runs.md new file mode 100644 index 0000000000..1f2783fa22 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/multi-phase-runs.md @@ -0,0 +1,29 @@ +--- +title: Multi-Phase Runs +sidebar_label: Multi-Phase Runs +--- + + + +Kurtosis environment definitions are encapsulated inside [Starlark scripts][starlark-explanation], and these scripts can be bundled into [packages][packages]. + +Much like Spark, Gradle, Cypress, and Flink, a multi-phase approach is used when Kurtosis runs Starlark: + + +1. **Interpretation Phase:** The Starlark is uploaded to the Kurtosis engine and the Starlark code is run. Each [Starlark Kurtosis instruction][starlark-instructions] adds a step to a plan of instructions to execute, _but the instruction isn't executed yet_. +1. **Validation Phase:** The plan of instructions is validated to ensure port dependencies are referencing existing ports, container images exist, duplicate services aren't being created, etc. +1. **Execution Phase:** The validated plan of instructions is executed, in the order they were defined. + +Practically, the user should be aware that: + +- Running [a Kurtosis Starlark instruction][starlark-instructions] does not execute the instruction on-the-spot; it instead adds the instruction to a plan of instructions to execute during the Execution Phase. +- Any value returned by a function in Starlark is not the actual value - it is [a future reference that Kurtosis will replace during the Execution Phase when the value actually exists][future-references-reference]. + +To read about why Kurtosis uses this multi-phase approach, [see here][multi-phase-runs-explanation]. + + +[starlark-explanation]: ../explanations/starlark.md +[starlark-instructions]: ./starlark-instructions.md +[packages]: ./packages.md +[multi-phase-runs-explanation]: ../explanations/why-multi-phase-runs.md +[future-references-reference]: ./future-references.md diff --git a/docs/versioned_docs/version-0.70.6/reference/packages.md b/docs/versioned_docs/version-0.70.6/reference/packages.md new file mode 100644 index 0000000000..9e8fe4ff98 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/packages.md @@ -0,0 +1,112 @@ +--- +title: Packages +sidebar_label: Packages +--- + +:::info +Packages are a part of the Kurtosis package system. To read about the package system in detail, [see here][how-do-kurtosis-imports-work-explanation]. +::: + + + +A Kurtosis package is a: + +- A directory +- Plus all its contents +- That contains [a `kurtosis.yml` file][kurtosis-yml] with the package's name, which will be the [locator][locators] root for the package + +Kurtosis packages are [the system by which Starlark scripts can include external resources][how-do-kurtosis-imports-work-explanation]. + +Note that, when developing locally, the GitHub repo referred to in the package name does not need to exist. + +Kurtosis packages are shared simply by pushing to GitHub (e.g. [these are the packages we administer][kurtosis-managed-packages]). + +For example, suppose there is a repo called `package-repo` by the author `package-author` whose internal directory structure looks like so: + +``` +/ + package-repo + my-package + kurtosis.yml + main.star + helpers + helpers.star +``` + +whose `kurtosis.yml` file looked like so: + +```yaml +name: github.com/package-author/package-repo/my-package +``` + +The package would be called `github.com/package-author/package-repo/my-package`. It should get pushed to the `package-repo` repo owned by the `package-author` user on GitHub. + +Packages are referenced indirectly, as the [locators][locators] used to specify external resources in a Starlark script will contain the package name where the resource lives. + +For example: + +```python +helpers = import_module("github.com/package-author/package-repo/my-package/helpers/helpers.star") +``` + +would be used to import the `helpers.star` file into a Starlark script. + + +The Kurtosis engine will automatically download dependency packages from GitHub when running a Starlark script. + +### Runnable Packages +A Kurtosis package that has a `main.star` file next to its `kurtosis.yml` file is called a "runnable package". The `main.star` file of a runnable package must have a `run(plan)` method like so: + +```python +def run(plan): + print("Hello, world.") +``` + +:::info +More on the `plan` parameter [here][plan]. +::: + +Runnable packages can be executed from the CLI in one of three ways: + +```bash +# OPTION 1: Point to a directory with a `kurtosis.yml` and `main.star` on local filesystem +kurtosis run /path/to/runnable/package/root +``` + +```bash +# OPTION 2: Point to a `kurtosis.yml` on the local filesystem with a `main.star` next to it on local fileesystem +kurtosis run /path/to/runnable/package/root/kurtosis.yml +``` + +```bash +# OPTION 3: Pass in a remote package name to run from GitHub +kurtosis run github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml +``` + +:::tip +If you want to run a non-main branch, tag or commit use the following syntax +`kurtosis run github.com/package-author/package-repo@tag-branch-commit` +::: + +All these will call the `run(plan)` function of the package's `main.star`. + +### Arguments +To accept parameters to the `run(plan)` function, the function should accept an `args` parameter: + +```python +def run(plan, args): + print("Hello, " + args.name) +``` + +To pass parameters to the `run(plan, args)` function, a JSON object should be passed as the second positional argument after the script or package path: + +``` +kurtosis run github.com/package-author/package-repo/path/to/directory-with-kurtosis.yml '{"name": "Joseph"}' +``` + + +[kurtosis-yml]: ./kurtosis-yml.md +[locators]: ./locators.md +[kurtosis-managed-packages]: https://github.com/kurtosis-tech?q=package+in%3Aname&type=all&language=&sort= +[how-do-kurtosis-imports-work-explanation]: ../explanations/how-do-kurtosis-imports-work.md +[plan]: ./plan.md diff --git a/docs/versioned_docs/version-0.70.6/reference/plan.md b/docs/versioned_docs/version-0.70.6/reference/plan.md new file mode 100644 index 0000000000..170710b357 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/plan.md @@ -0,0 +1,51 @@ +--- +title: Plan +sidebar_label: Plan +--- + +The `plan` object contains all enclave-modifying methods like `add_service`, `remove_service`, `upload_files` etc; for more look into [Starlark instructions][starlark-instructions]. All of the methods that come with the `plan` add to the list of instructions that Kurtosis would eventually execute in the Execution phase of [the multi-phase run][multi-phase-runs]. + +The `plan` object is the first object that gets injected into the `run` method in the `main.star` of your package or your standalone script. The package or script author must ensure that the first argument is an argument called `plan`, and then use the enclave-modifying functions from it. The author also must pass the `plan` methods down to any other scripts or packages that require enclave-modifying functions. + +Here's an example :- + +Imagine you have a `kurtosis.yml` that looks like +```yaml +name: "github.com/test-author/test-package" +``` + +Further with a `main.star` at the root of the package that looks like +```py +datastore = import_module("github.com/test-author/test-package/lib/datastore.star") + +def run(plan): + datastore.create_datastore(plan) +``` + +and the `lib/datastore.star` looks like +```py +def create_datastore(plan): + plan.add_service( + service_name = "datastore-service", + config = ServiceConfig( + image = "kurtosistech/example-datastore-server" + ) + ) +``` + +To accept [arguments][arguments] in the `run` function, pass them as the second parameter like so + +```py +def run(plan, args): + pass +``` + +:::caution +Any value returned by a `plan` function is a [future-reference][future-reference]. This means that you can't run conditionals or interpretation time methods like `string.split` on it. +::: + + +[future-reference]: ./future-references.md +[starlark-instructions]: ./starlark-instructions.md +[arguments]: ./packages.md#arguments +[multi-phase-runs]: ./multi-phase-runs.md \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/resource-identifier.md b/docs/versioned_docs/version-0.70.6/reference/resource-identifier.md new file mode 100644 index 0000000000..9ce824ccc2 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/resource-identifier.md @@ -0,0 +1,70 @@ +--- +title: Resource Identifier +sidebar_label: Resource Identifier +--- + +Kurtosis has multiple ways to identify a given resource within Kurtosis. These include UUIDs, shortened UUIDs and names. Together these are called resource identifiers. + +A resource identifier as mentioned above is the union of the following - + +- UUID - a UUID or a Universally Unique Identifier within Kurtosis is a 32 character-long hex-encoded string generated using [UUID v4][uuidv4]. Kurtosis automatically assigns a UUID to resources. +- Shortened UUID - A shortened UUID is the first 12 characters of a UUID. As the shortened UUID is just 12 characters, it isn't guaranteed to be unique. In case of conflicts, Kurtosis tells the user about the ambiguity and provides +a list of matching full UUIDs. +- Name - A name is what a user gives to the underlying resource. For some resources Kurtosis automatically generates the name if the user doesn't specify it. Note a name is only point-in-time unique; you can have the same name identifying different resources over time. In case of conflicts, Kurtosis tells the user about the ambiguity and provides a list of matching full UUIDs. + +For example, let's assume an enclave was created with the name `winter-sun`. If you run `kurtosis enclave inspect winter-sun` you would get something like - + +``` +UUID: edfdbf5766f6 +Enclave Name: winter-snow +Enclave Status: RUNNING +Creation Time: Tue, 24 Jan 2023 16:45:13 GMT +API Container Status: RUNNING +API Container Host GRPC Port: 127.0.0.1:54433 +API Container Host GRPC Proxy Port: 127.0.0.1:54434 + +========================================== User Services ========================================== +UUID Name Ports Status +``` + +Notice how Kurtosis shows the shortened UUID by default. All CLI commands show +shortened UUIDs by default; if you want to see full UUIDs you can use the `--full-uuids` flag with the command. Rerunning the above command with `--full-uuids` you'd get + +``` +UUID: edfdbf5766f64a649efca11f51ebb4c1 +Enclave Name: winter-snow +Enclave Status: RUNNING +Creation Time: Tue, 24 Jan 2023 16:45:13 GMT +API Container Status: RUNNING +API Container Host GRPC Port: 127.0.0.1:54433 +API Container Host GRPC Proxy Port: 127.0.0.1:54434 + +========================================== User Services ========================================== +UUID Name Ports Status +``` + +Whenever a user is querying Kurtosis using the CLI & SDK, the user can use any of UUID, shortened UUID & name. The CLI informs the user about this support by calling the relevant argument `resource-identifier`, like below + +``` +Usage: + kurtosis enclave inspect [flags] enclave-identifier + +Flags: + --full-uuids If true then Kurtosis prints full UUIDs instead of shortened UUIDs. Default false. + -h, --help help for inspect + +Global Flags: + --cli-log-level string Sets the level that the CLI will log at (panic|fatal|error|warning|info|debug|trace) (default "info") +``` + +Resource Identifiers are supported for the following resources inside of Kurtosis + +- [Files Artifacts][files-artifacts] +- [Services][services] +- [Enclaves][enclaves] + + +[uuidv4]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) +[files-artifacts]: ./files-artifacts.md +[services]: ./glossary.md#user-service +[enclaves]: ./glossary.md#enclave diff --git a/docs/versioned_docs/version-0.70.6/reference/sdk.md b/docs/versioned_docs/version-0.70.6/reference/sdk.md new file mode 100644 index 0000000000..077d993cad --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/sdk.md @@ -0,0 +1,675 @@ +--- +title: SDK +sidebar_label: SDK +slug: /sdk +sidebar_position: 2 +toc_min_heading_level: 2 +toc_max_heading_level: 2 +--- + +This page documents the objects and functions contained in [the Kurtosis SDK][kurtosis-sdk-repo]. + +:::tip +The sidebar on the right can be used to quickly navigate classes. +::: + +KurtosisContext +--------------- +A connection to a Kurtosis engine, used for manipulating enclaves. + +### `createEnclave(String enclaveName, boolean isPartitioningEnabled) -> [EnclaveContext][enclavecontext] enclaveContext` +Creates a new Kurtosis enclave using the given parameters. + +**Args** +* `enclaveName`: The name to give the new enclave. +* `isPartitioningEnabled`: If set to true, the enclave will be set up to allow for repartitioning. This will make service addition & removal take slightly longer, but allow for calls to [EnclaveContext.repartitionNetwork][enclavecontext_repartitionnetwork]. + +**Returns** +* `enclaveContext`: An [EnclaveContext][enclavecontext] object representing the new enclave. + +### `getEnclaveContext(String enclaveIdentifier) -> [EnclaveContext][enclavecontext] enclaveContext` +Gets the [EnclaveContext][enclavecontext] object for the given enclave ID. + +**Args** +* `enclaveIdentifier`: The [identifier][identifier] of the enclave. + +**Returns** +* `enclaveContext`: The [EnclaveContext][enclavecontext] representation of the enclave. + +### `getEnclaves() -> Enclaves enclaves` +Gets the enclaves that the Kurtosis engine knows about. + +**Returns** +* `enclaves`: The [Enclaves][enclaves] representation of all enclaves that Kurtosis the engine knows about. + +### `getEnclave(String enclaveIdentifier) -> EnclaveInfo enclaveInfo` +Gets information about the enclave for the given identifier + +**Args** +* `enclaveIdentifier`: The [identifier][identifier] of the enclave. + +**Returns** +* `enclaves`: The [EnclaveInfo][enclaveinfo] object representing the enclave + +### `stopEnclave(String enclaveIdentifier)` +Stops the enclave with the given [identifier][identifier], but doesn't destroy the enclave objects (containers, networks, etc.) so they can be further examined. + +**NOTE:** Any [EnclaveContext][enclavecontext] objects representing the stopped enclave will become unusable. + +**Args** +* `enclaveIdentifier`: [Identifier][identifier] of the enclave to stop. + +### `destroyEnclave(String enclaveIdentifier)` +Stops the enclave with the given [identifier][identifier] and destroys the enclave objects (containers, networks, etc.). + +**NOTE:** Any [EnclaveContext][enclavecontext] objects representing the stopped enclave will become unusable. + +**Args** +* `enclaveIdentifier`: [Identifier][identifier] of the enclave to destroy. + +### `clean(boolean shouldCleanAll) -> []EnclaveNameAndUuid RemovedEnclaveNameAndUuids` +Destroys enclaves in the Kurtosis engine. + +**Args** +* `shouldCleanAll`: If set to true, destroys running enclaves in addition to stopped ones. + +**Returns** +* `RemovedEnclaveNameAndUuids`: A list of enclave uuids and names that were removed succesfully + +### `getServiceLogs(String enclaveIdentifier, Set serviceUuids, Boolean shouldFollowLogs, LogLineFilter logLineFilter) -> ServiceLogsStreamContent serviceLogsStreamContent` +Get and start a service container logs stream (showed in ascending order, with the oldest line first) from services identified by their UUID. + +**Args** +* `enclaveIdentifier`: [Identifier][identifier] of the services' enclave. +* `serviceUuids`: A set of service UUIDs identifying the services from which logs should be retrieved. +* `shouldFollowLogs`: If it's true, the stream will constantly send the new log lines. if it's false, the stream will be closed after the last created log line is sent. +* `logLineFilter`: The [filter][loglinefilter] that will be used for filtering the returned log lines + +**Returns** +* `serviceLogsStreamContent`: The [ServiceLogsStreamContent][servicelogsstreamcontent] object which wrap all the information coming from the logs stream. + +### `getExistingAndHistoricalEnclaveIdentifiers() -> EnclaveIdentifiers enclaveIdentifiers` + +Get all (active & deleted) historical [identifiers][identifier] for the currently +running Kurtosis engine. + +**Returns** +* `enclaveIdentifiers` The [EnclaveIdentifiers][enclave-identifiers] which provides user-friendly ways to lookup enclave identifier information. + +EnclaveIdentifiers +------------------- +This class is a representation of identifiers of enclaves. + +### `getEnclaveUuidForIdentifier(string identifier) -> EnclaveUUID enclaveUuid, Error` +Returns the UUID that matches the given identifier. If there are no matches it returns +an error instead. + +**Args** +* `identifier`: A enclave identifier string + +**Returns** +* `enclaveUuid`: The UUID for the enclave identified by the `identifier`. + +### `getOrderedListOfNames() -> []String enclaveNames` +Returns an ordered list of names for all the enclaves registered with the engine. This is useful +if users want to enumerate all enclave names, say for an autocomplete like function. + +**Returns** +* `enclaveNames`: This is a sorted list of enclave names + +ServiceLogsStreamContent +------------------------ +This class is the representation of the content sent during a service logs stream communication. This wrapper includes the service's logs content and the not found service UUIDs. + +### `getServiceLogsByServiceUuids() -> Map> serviceLogsByServiceUuids` +Returns the user service logs content grouped by the service's UUID. + +**Returns** +* `serviceLogsByServiceUuids`: A map containing a list of the [ServiceLog][servicelog] objects grouped by service UUID. + +### `getNotFoundServiceUuids() -> Set notFoundServiceUuids` +Returns the not found service UUIDs. The UUIDs may not be found either because they don't exist, or because the services haven't sent any logs. + +**Returns** +* `notFoundServiceUuids`: A set of not found service UUIDs + +ServiceLog +---------- +This class represent single service's log line information + +### `getContent() -> String content` + +**Returns** +* `content`: The log line string content + +LogLineFilter +------------- +This class is used to specify the match used for filtering the service's log lines. There are a couple of helpful constructors that can be used to generate the filter type + +### `NewDoesContainTextLogLineFilter(String text) -> LogLineFilter logLineFilter` +Returns a LogLineFilter type which must be used for filtering the log lines containing the text match + +**Args** +* `text`: The text that will be used to match in the log lines + +**Returns** +* `logLineFilter`: The does-contain-text-match log line filter + +### `NewDoesNotContainTextLogLineFilter(String text) -> LogLineFilter logLineFilter` +Returns a LogLineFilter type which must be used for filtering the log lines that do not contain the text match + +**Args** +* `text`: The text that will be used to match in the log lines + +**Returns** +* `logLineFilter`: The does-not-contain-text-match log line filter + +### `NewDoesContainMatchRegexLogLineFilter(String regex) -> LogLineFilter logLineFilter` +Returns a LogLineFilter type which must be used for filtering the log lines containing the regex match, [re2 syntax regex may be used][google_re2_syntax_docs] + +**Args** +* `regex`: The regex expression that will be used to match in the log lines + +**Returns** +* `logLineFilter`: The does-contain-regex-match log line filter + +### `NewDoesNotContainMatchRegexLogLineFilter(String regex) -> LogLineFilter logLineFilter` +Returns a LogLineFilter type which must be used for filtering the log lines that do not contain the regex match, [re2 syntax regex may be used][google_re2_syntax_docs] + +**Args** +* `regex`: The regex expression that will be used to match in the log lines + +**Returns** +* `logLineFilter`: The does-not-contain-regex-match log line filter + +Enclaves +-------- + +This Kurtosis provided class is a collection of various different [EnclaveInfo][enclaveinfo] objects, by UUID, shortened UUID, and name. + +### Map `enclavesByUuid` + +A map from UUIDs to the enclave info for the enclave with the given UUID. + +### Map `enclavesByName` + +A map from names to the enclave info for the enclave with the given name + +### Map `enclavesByShortenedUuid` + +A map from shortened UUID (first 12 characters of UUID) to the enclave infos of the enclaves it matches too. + +EnclaveInfo +----------- + +This Kurtosis provided class contains information about enclaves. This class just contains data and no methods to manipulate enclaves. Users must use [EnclaveContext][enclavecontext] to modify the state of an enclave. + +### `getEnclaveUuid() -> EnclaveUuid` +Gets the UUID of the enclave that this [EnclaveInfo][enclaveinfo] object represents. + +### `getShortenedUuid() -> String` +Gets the shortened UUID of the enclave that this [EnclaveInfo][enclaveinfo] object represents. + +### `getName() -> String` +Gets the name of the enclave that this [EnclaveInfo][enclaveinfo] object represents. + +### `getCreationTime() -> Timestamp` +Gets the timestamp at which the enclave that this [EnclaveInfo][enclaveinfo] object represents was created. + +### `getCreationTime() -> Timestamp` +Gets the timestamp at which the enclave that this [EnclaveInfo][enclaveinfo] object represents was created. + +### `getContainersStatus() -> Status` +Gets the current status of the container running the enclave represented by this [EnclaveInfo][enclaveinfo]. Is one of 'EMPTY', 'RUNNING' and 'STOPPED'. + +EnclaveContext +-------------- +This Kurtosis-provided class is the lowest-level representation of a Kurtosis enclave, and provides methods for inspecting and manipulating the contents of the enclave. + +### `getEnclaveUuid() -> EnclaveUuid` +Gets the UUID of the enclave that this [EnclaveContext][enclavecontext] object represents. + +### `getEnclaveName() -> String` +Gets the name of the enclave that this [EnclaveContext][enclavecontext] object represents. + +### `runStarlarkScript(String serializedStarlarkScript, Boolean dryRun) -> (Stream responseLines, Error error)` + +Run a provided Starlark script inside the enclave. + +**Args** + +* `serializedStarlarkScript`: The Starlark script provided as a string +* `dryRun`: When set to true, the Kurtosis instructions are not executed. + +**Returns** + +* `responseLines`: A stream of [StarlarkRunResponseLine][starlarkrunresponseline] objects + +### `runStarlarkPackage(String packageRootPath, String serializedParams, Boolean dryRun) -> (Stream responseLines, Error error)` + +Run a provided Starlark script inside the enclave. + +**Args** + +* `packageRootPath`: The path to the root of the package +* `serializedParams`: The parameters to pass to the package for the run. It should be a serialized JSON string. +* `dryRun`: When set to true, the Kurtosis instructions are not executed. + +**Returns** + +* `responseLines`: A stream of [StarlarkRunResponseLine][starlarkrunresponseline] objects + +### `runStarlarkRemotePackage(String packageId, String serializedParams, Boolean dryRun) -> (Stream responseLines, Error error)` + +Run a Starlark script hosted in a remote github.com repo inside the enclave. + +**Args** + +* `packageId`: The ID of the package pointing to the github.com repo hosting the package. For example `github.com/kurtosistech/datastore-army-package` +* `serializedParams`: The parameters to pass to the package for the run. It should be a serialized JSON string. +* `dryRun`: When set to true, the Kurtosis instructions are not executed. + +**Returns** + +* `responseLines`: A stream of [StarlarkRunResponseLine][starlarkrunresponseline] objects + +### `runStarlarkScriptBlocking(String serializedStarlarkScript, Boolean dryRun) -> (StarlarkRunResult runResult, Error error)` + +Convenience wrapper around [EnclaveContext.runStarlarkScript][enclavecontext_runstarlarkscript], that blocks until the execution of the script is finished and returns a single [StarlarkRunResult][starlarkrunresult] object containing the result of the run. + +### `runStarlarkPackageBlocking(String packageRootPath, String serializedParams, Boolean dryRun) -> (StarlarkRunResult runResult, Error error)` + +Convenience wrapper around [EnclaveContext.runStarlarkPackage][enclavecontext_runstarlarkpackage], that blocks until the execution of the package is finished and returns a single [StarlarkRunResult][starlarkrunresult] object containing the result of the run. + +### `runStarlarkRemotePackageBlocking(String packageId, String serializedParams, Boolean dryRun) -> (StarlarkRunResult runResult, Error error)` + +Convenience wrapper around [EnclaveContext.runStarlarkRemotePackage][enclavecontext_runstarlarkremotepackage], that blocks until the execution of the package is finished and returns a single [StarlarkRunResult][starlarkrunresult] object containing the result of the run. + + +### `registerFilesArtifacts(Map filesArtifactUrls)` +Downloads the given files artifacts to the Kurtosis engine, associating them with the given IDs, so they can be mounted inside a service's filespace at creation time via [ContainerConfig.filesArtifactMountpoints][containerconfig_filesartifactmountpoints]. + +**Args** + +* `filesArtifactUrls`: A map of files_artifact_id -> url, where the ID is how the artifact will be referenced in [ContainerConfig.filesArtifactMountpoints][containerconfig_filesartifactmountpoints] and the URL is the URL on the web where the files artifact should be downloaded from. + +### `addServiceToPartition(ServiceID serviceId, PartitionID partitionId, ContainerConfig containerConfig) -> ServiceContext serviceContext` +Starts a new service in the enclave with the given service ID, inside the partition with the given ID, using the given container config. + +**Args** + +* `serviceId`: The ID that the new service should have. +* `partitionId`: The ID of the partition that the new service should be started in. This can be left blank to start the service in the default partition if it exists (i.e. if the enclave hasn't been repartitioned and the default partition removed). +* `containerConfig`: A [ContainerConfig][containerconfig] object indicating how to configure the service. + +**Returns** + +* `serviceContext`: The [ServiceContext][servicecontext] representation of a service running in a Docker container. Port information can be found in `ServiceContext.GetPublicPorts()`. The port spec strings that the service declared (as defined in [ContainerConfig.usedPorts][containerconfig_usedports]), mapped to the port on the host machine where the port has been bound to. This allows you to make requests to a service running in Kurtosis by making requests to a port on your local machine. If a port was not bound to a host machine port, it will not be present in the map (and if no ports were bound to host machine ports, the map will be empty). + +### `addServicesToPartition(Map containerConfigs, PartitionID partitionId) -> (Map successfulServices, Map failedServices)` +Start services in bulk in the enclave with the given service IDs, inside the partition with the given ID, using the given container config. + +**Args** + +* `containerConfigs`: A mapping of service IDs to start in the enclave to their `containerConfig` indicating how to configure the service. +* `partitionId`: The ID of the partition that the new service should be started in. This can be left blank to start the service in the default partition if it exists (i.e. if the enclave hasn't been repartitioned and the default partition removed). + +**Returns** + +* `successfulServices`: A mapping of service IDs that were successfully started in the enclave to their respective [ServiceContext][servicecontext] representation. +* `failedServices`: A mapping of service IDs to the errors the caused that prevented the services from being added successfully to the enclave. + +### `addService(ServiceID serviceId, ContainerConfig containerConfig) -> (ServiceContext serviceContext)` +Convenience wrapper around [EnclaveContext.addServiceToPartition][enclavecontext_addservicetopartition], that adds the service to the default partition. Note that if the enclave has been repartitioned and the default partition doesn't exist anymore, this method will fail. + +### `getServiceContext(String serviceIdentifier) -> ServiceContext serviceContext` +Gets relevant information about a service (identified by the given service [identifier][identifier]) that is running in the enclave. + +**Args** + +* `serviceIdentifier`: The [identifier(name, UUID or short name)][identifier] of the target service + +**Returns** + +The [ServiceContext][servicecontext] representation of a service running in a Docker container. + +### `getServices() -> Map serviceIdentifiers` +Gets the Name and UUID of the current services in the enclave. + +**Returns** + +* `serviceIdentifiers`: A map of objects containing a mapping of Name -> UUID for all the services inside the enclave + +### `uploadFiles(String pathToUpload, String artifactName) -> FileArtifactUUID, FileArtifactName, Error` +Takes a filepath or directory path that will be compressed and uploaded to the Kurtosis filestore for use with [ContainerConfig.filesArtifactMountpoints][containerconfig_filesartifactmountpoints]. + +If a directory is specified, the contents of the directory will be uploaded to the archive without additional nesting. Empty directories cannot be uploaded. + +**Args** + +* `pathToUpload`: Filepath or dirpath on the local machine to compress and upload to Kurtosis. +* `artifactName`: The name to refer the artifact with. + +**Returns** + +* `FileArtifactUUID`: A unique ID as a string identifying the uploaded files, which can be used in [ContainerConfig.filesArtifactMountpoints][containerconfig_filesartifactmountpoints]. +* `FileArtifactName`: The name of the file-artifact, it is auto-generated if `artitfactName` is an empty string. + +### `storeWebFiles(String urlToDownload, String artifactName)` +Downloads a files-containing `.tgz` from the given URL to the Kurtosis engine, so that the files inside can be mounted inside a service's filespace at creation time via [ContainerConfig.filesArtifactMountpoints][containerconfig_filesartifactmountpoints]. + +**Args** + +* `urlToDownload`: The URL on the web where the files-containing `.tgz` should be downloaded from. +* `artifactName`: The name to refer the artifact with. + +**Returns** + +* `UUID`: A unique ID as a string identifying the downloaded, which can be used in [ContainerConfig.filesArtifactMountpoints][containerconfig_filesartifactmountpoints]. + +### `getExistingAndHistoricalServiceIdentifiers() -> ServiceIdentifiers serviceIdentifiers` + +Get all (active & deleted) historical [identifiers][identifier] for services for the enclave represented by the [EnclaveContext][enclavecontext]. + +**Returns** +* `serviceIdentifiers`: The [ServiceIdentifiers][service-identifiers] which provides user-friendly ways to lookup service identifier information. + +### `getAllFilesArtifactNamesAndUuids() -> []FilesArtifactNameAndUuid filesArtifactNamesAndUuids` + +Get a list of all files artifacts that are registered with the enclave represented by the [EnclaveContext][enclavecontext] + +**Returns** +* `filesArtifactNameAndUuids`: A list of files artifact names and their corresponding uuids. + +ServiceIdentifiers +------------------- +This class is a representation of service identifiers for a given enclave. + +### `getServiceUuidForIdentifier(string identifier) -> ServiceUUID serviceUUID, Error` +Returns the UUID that matches the given identifier. If there are no matches it returns +an error instead. + +**Args** +* `identifier`: A service identifier string + +**Returns** +* `enclaveUuid`: The UUID for the service identified by the `identifier`. + +### `getOrderedListOfNames() -> []String serviceNames` +Returns an ordered list of names for all the services in the enclave. This is useful +if users want to enumerate all service names, say for an autocomplete like function. + +**Returns** +* `serviceNames`: This is a sorted list of service names + +ModuleContext +------------- +**DEPRECATED: Use `runStarlarkScript` and `runStarlarkPackage` instead** + +This Kurtosis-provided class is the lowest-level representation of a Kurtosis module - a Docker container with a connection to the Kurtosis engine that responds to commands. + +### `execute(String serializedParams) -> String serializedResult` +**DEPRECATED: Use `runStarlarkScript` and `runStarlarkPackage` instead** + +Some modules are considered executable, meaning they respond to an "execute" command. This function will send the execute command to the module with the given serialized args, returning the serialized result. The serialization format of args & response will depend on the module. If the module isn't executable (i.e. doesn't respond to an "execute" command) then an error will be thrown. + +**Args** + +* `serializedParams`: Serialized data containing args to the module's execute function. Consult the documentation for the module you're using to determine what this should contain. + +**Returns** + +* `serializedResult`: Serialized data containing the results of executing the module. Consult the documentation for the module you're using to determine what this will contain. + +PartitionConnection +------------------- +This interface represents the network state between two partitions (e.g. whether network traffic is blocked, being partially dropped, etc.). + +The three types of partition connections are: unblocked (all traffic is allowed), blocked (no traffic is allowed), and soft (packets are partially dropped). Each type of partition connection has a constructor that can be used to create them. + +The soft partition constructor receives one parameter, `packetLossPercentage`, which sets the percentage of packet loss in the connection between the services that are part of the partition. + +Unblocked partitions and blocked partitions have parameter-less constructors. + +ContainerConfig +--------------- +Object containing information Kurtosis needs to create and run the container. This config should be created using [ContainerConfigBuilder][containerconfigbuilder] instances. + +### String image +The name of the container image that Kurtosis should use when creating the service's container (e.g. `my-repo/my-image:some-tag-name`). + +### `Map usedPorts` +The ports that the container will be listening on, identified by a user-friendly ID that can be used to select the port again in the future (e.g. via [ServiceContext.getPublicPorts][servicecontext_getpublicports]. + +### `Map filesArtifactMountpoints` +Sometimes a service needs files to be available before it starts (e.g. starting a service with a 5 GB Postgres database mounted). To ease this pain, Kurtosis allows you to specify gzipped TAR files that Kurtosis will uncompress and mount at locations on your service containers. These "files artifacts" will need to have been stored in Kurtosis beforehand using methods like [EnclaveContext.uploadFiles][enclavecontext_uploadfiles]. + +This property is therefore a map of the files artifact ID -> path on the container where the uncompressed artifact contents should be mounted, with the file artifact IDs corresponding to the ID returned by files-storing methods like [EnclaveContext.uploadFiles][enclavecontext_uploadfiles]. + +E.g. if I've previously uploaded a set of files using [EnclaveContext.uploadFiles][enclavecontext_uploadfiles] and Kurtosis has returned me the ID `813bdb20-3aab-4c5b-a0f5-a7deba7bf0d7`, I might ask Kurtosis to mount the contents inside my container at the `/database` path using a map like `{"813bdb20-3aab-4c5b-a0f5-a7deba7bf0d7": "/database"}`. + +### `List entrypointOverrideArgs` +You often won't control the container images that you'll be using in your testnet, and the `ENTRYPOINT` statement hardcoded in their Dockerfiles might not be suitable for what you need. This function allows you to override these statements when necessary. + +### `List cmdOverrideArgs` +You often won't control the container images that you'll be using in your testnet, and the `CMD` statement hardcoded in their Dockerfiles might not be suitable for what you need. This function allows you to override these statements when necessary. + +### `Map environmentVariableOverrides` +Defines environment variables that should be set inside the Docker container running the service. This can be necessary for starting containers from Docker images you don't control, as they'll often be parameterized with environment variables. + +### `uint64 cpuAllocationMillicpus` +Allows you to set an allocation for CPU resources available in the underlying host container of a service. The metric used to measure `cpuAllocation` is `millicpus`, 1000 millicpus is equivalent to 1 CPU on the underlying machine. This metric is identical [Docker's measure of `cpus`](https://docs.docker.com/config/containers/resource_constraints/#:~:text=Description-,%2D%2Dcpus%3D%3Cvalue%3E,-Specify%20how%20much) and [Kubernetes measure of `cpus` for limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-cpu). Setting `cpuAllocationMillicpus=1500` is equivalent to setting `cpus=1.5` in Docker and `cpus=1.5` or `cpus=1500m` in Kubernetes. If set, the value must be a nonzero positive integer. If unset, there will be no constraints on CPU usage of the host container. + +### `uint64 memoryAllocationMegabytes` +Allows you to set an allocation for memory resources available in the underlying host container of a service. The metric used to measure `memoryAllocation` is `megabytes`. Setting `memoryAllocation=1000` is equivalent to setting the memory limit of the underlying host machine to `1e9 bytes` or `1GB`. If set, the value must be a nonzero positive integer of at least `6 megabytes` as Docker requires this as a minimum. If unset, there will be no constraints on memory usage of the host container. For information on memory limits in your underlying container engine, view [Docker](https://docs.docker.com/config/containers/resource_constraints/)'s and [Kubernetes](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)'s docs. + +### `String privateIPAddrPlaceholder` +The placeholder string used within `entrypointOverrideArgs`, `cmdOverrideArgs`, and `environmentVariableOverrides` that gets replaced with the private IP address of the container inside Docker/Kubernetes before the container starts. This defaults to `KURTOSIS_IP_ADDR_PLACEHOLDER` if this isn't set. +The user needs to make sure that they provide the same placeholder string for this field that they use in `entrypointOverrideArgs`, `cmdOverrideArgs`, and `environmentVariableOverrides`. + + +ContainerConfigBuilder +------------------------------ +The builder that should be used to create [ContainerConfig][containerconfig] instances. The functions on this builder will correspond to the properties on the [ContainerConfig][containerconfig] object, in the form `withPropertyName` (e.g. `withUsedPorts` sets the ports used by the container). + + +StarlarkRunResponseLine +----------------------- + +This is a union object representing a single line returned by Kurtosis' Starlark runner. All Starlark run endpoints will return a stream of this object. + +Each line is one of: + +### [StarlarkInstruction][starlarkinstruction] `instruction` +An instruction that is _about to be_ executed. + +### [StarlarkInstructionResult][starlarkinstructionresult] `instructionResult` +The result of an instruction that was successfully executed + +### [StarlarkError][starlarkerror] `error` +The error that was thrown running the Starlark code + +### [StarlarkRunProgress][starlarkrunprogress] `progressInfo` +Regularly during the run of the code, Kurtosis' Starlark engine will send progress information through the stream to account for progress that was made running the code. + +StarlarkInstruction +------------------- + +`StarlarkInstruction` represents a Starlark instruction that is currently being executed. It contains the following fields: + +* `instructionName`: the name of the instruction + +* `instructionPosition`: the position of the instruction in the source code. It iscomposed of (filename, line number, column number) + +* `arguments`: The list of arguments provided to this instruction. Each argument is composed of an optional name (if it was named in the source script) and its serialized value + +* `executableInstruction`: A single string representing the instruction in valid Starlark code + +StarlarkInstructionResult +------------------------- + +`StarlarkInstructionResult` is the result of an instruction that was successfully run against Kurtosis engine. It is a single string field corresponding to the output of the instruction. + +StarlarkError +------------- + +Errors can be of three kind: + +* Interpretation error: these errors happens before Kurtosis was able to execute the script. It typically means there's a syntax error in the provided Starlark code. The error message should point the users to where the code is incorrect. + +* Validation error: these errors happens after interpretation was successful, but before the execution actually started in Kurtosis. Before starting the execution, Kurtosis runs some validation on the instructions that are about to be executed. The error message should contain more information on which instruction is incorrect. + +* Execution error: these errors happens during the execution of the script against Kurtosis engine. More information is available in the error message. + +StarlarkRunProgress +------------------- + +`StarlarkRunProgress` accounts for progress that is made during a Starlark run. It contains three fields: + +* `totalSteps`: The total number of steps for this run + +* `currentStepNumber`: The number of the step that is currently being executed + +* `currentStepInfo`: A string field with some information on the current step being executed. + +StarlarkRunResult +----------------- + +`StarlarkRunResult` is the object returned by the blocking functions to run Starlark code. It is similar to [RunStarlarkResponseLine][runstarlarkresponseline] except that it is not a union object: + +* `instructions`: the [Starlark Instruction][starlarkinstruction] that were run + +* `insterpretationError`: a potential Starlark Interpretation error (see [StarlarkError][starlarkerror] + +* `validationErrors`: potential Starlark Validation errors (see [StarlarkError][starlarkerror] + +* `executionError`: a potential Starlark Execution error (see [StarlarkError][starlarkerror] + +* `runOutput`: The full output of the run, composed of the concatenated output for each instruction that was executed (separated by a newline) + +ServiceContext +-------------- +This Kurtosis-provided class is the lowest-level representation of a service running inside a Docker container. It is your handle for retrieving container information and manipulating the container. + +### `getServiceName() -> ServiceName` +Gets the Name that Kurtosis uses to identify the service. + +**Returns** + +The service's Name. + +### `getServiceUuid() -> ServiceUUID` +Gets the UUID (Universally Unique Identifier) that Kurtosis creates and uses to identify the service. +The differences with the Name is that this one is created by Kurtosis, users can't specify it, and this never can be repeated, every new execution of the same service will have a new UUID + +**Returns** + +The service's UUID. + +### `getPrivateIpAddress() -> String` +Gets the IP address where the service is reachable at from _inside_ the enclave that the container is running inside. This IP address is how other containers inside the enclave can connect to the service. + +**Returns** + +The service's private IP address. + +### `getPrivatePorts() -> Map` +Gets the ports that the service is reachable at from _inside_ the enclave that the container is running inside. These ports are how other containers inside the enclave can connect to the service. + +**Returns** + +The ports that the service is reachable at from inside the enclave, identified by the user-chosen ID set in [ContainerConfig.usedPorts][containerconfig_usedports] when the service was created. + +### `getMaybePublicIpAddress() -> String` +If the service declared used ports in [ContainerConfig.usedPorts][containerconfig_usedports], then this function returns the IP address where the service is reachable at from _outside_ the enclave that the container is running inside. This IP address is how clients on the host machine can connect to the service. If no used ports were declared, this will be empty. + +**Returns** + +The service's public IP address, or an empty value if the service didn't declare any used ports. + +### `getPublicPorts() -> Map` +Gets the ports that the service is reachable at from _outside_ the enclave that the container is running inside. These ports are how clients on the host machine can connect to the service. If the service didn't declare any used ports in [ContainerConfig.usedPorts][containerconfig_usedports], this value will be an empty map. + +**Returns** + +The ports (if any) that the service is reachable at from outside the enclave, identified by the user-chosen ID set in [ContainerConfig.usedPorts][containerconfig_usedports] when the service was created. + +### `execCommand(List command) -> (int exitCode, String logs)` +Uses [Docker exec](https://docs.docker.com/engine/reference/commandline/exec/) functionality to execute a command inside the service's running Docker container. + +**Args** + +* `command`: The args of the command to execute in the container. + +**Returns** + +* `exitCode`: The exit code of the command. +* `logs`: The output of the run command, assuming a UTF-8 encoding. **NOTE:** Commands that output non-UTF-8 output will likely be garbled! + +TemplateAndData +------------------ + +This is an object that gets used by the [renderTemplates][enclavecontext_rendertemplates] function. +It has two properties. + +### String template +The template that needs to be rendered. We support Golang [templates](https://pkg.go.dev/text/template). The casing of the `keys` or `fields` inside the template must match the casing of the `fields` or the `keys` inside the data. + +### Any templateData +The data that needs to be rendered in the template. This will be converted into a JSON string before it gets sent over the wire. The elements inside the object should exactly match the keys in the template. If you are using a struct for `templateData` then the field names must start with an upper case letter to ensure that the field names are accessible outside of the structs own package. If you are using a map then you can keys that begin with lower case letters as well. + +Note, because of how we handle floating point numbers & large integers, if you pass a floating point number it will get +printed in the decimal notation by default. If you want to use modifiers like `{{printf .%2f | .MyFloat}}`, you'll have to use +the `Float64` method on the `json.Number` first, so above would look like `{{printf .2%f | .MyFloat.Float64}}`. + + + + + + +[kurtosis-sdk-repo]: https://github.com/kurtosis-tech/kurtosis/tree/main/api + +[servicelogsstreamcontent]: #servicelogsstreamcontent +[servicelog]: #servicelog + +[containerconfig]: #containerconfig +[containerconfig_usedports]: #mapportid-portspec-usedports +[containerconfig_filesartifactmountpoints]: #mapstring-string-filesartifactmountpoints + +[containerconfigbuilder]: #containerconfigbuilder + +[modulecontext]: #modulecontext + +[enclavecontext]: #enclavecontext +[enclavecontext_registerfilesartifacts]: #registerfilesartifactsmapfilesartifactid-string-filesartifacturls +[enclavecontext_addservice]: #addserviceserviceid-serviceid--funcstring-ipaddr---containerconfigcontainerconfig-containerconfigsupplier---servicecontextservicecontext-servicecontext +[enclavecontext_unpauseservice]: #unpauseserviceserviceid-serviceid + +[partitionconnection]: #partitionconnection + +[enclavecontext_runstarlarkscript]: #runstarlarkscriptstring-serializedstarlarkscript-boolean-dryrun---streamstarlarkrunresponseline-responselines-error-error +[enclavecontext_runstarlarkpackage]: #runstarlarkpackagestring-packagerootpath-string-serializedparams-boolean-dryrun---streamstarlarkrunresponseline-responselines-error-error +[enclavecontext_runstarlarkremotepackage]: #runstarlarkremotepackagestring-packageid-string-serializedparams-boolean-dryrun---streamstarlarkrunresponseline-responselines-error-error + +[starlarkrunresponseline]: #starlarkrunresponseline +[starlarkinstruction]: #starlarkinstruction +[starlarkinstructionresult]: #starlarkinstructionresult +[starlarkerror]: #starlarkerror +[starlarkrunprogress]: #starlarkrunprogress + +[servicecontext]: #servicecontext +[servicecontext_getpublicports]: #getpublicports---mapportid-portspec + +[templateanddata]: #templateanddata + +[kurtosiscontext_createenclave]: #createenclavestring-enclaveid-boolean-ispartitioningenabled---enclavecontextenclavecontext-enclavecontext + +[loglinefilter]: #loglinefilter +[google_re2_syntax_docs]: https://github.com/google/re2/wiki/Syntax + +[enclaveinfo]: #enclaveinfo +[enclaves]: #enclaves + +[identifier]: ../reference/resource-identifier.md +[enclave-identifiers]: #enclaveidentifiers +[service-identifiers]: #serviceidentifiers \ No newline at end of file diff --git a/docs/versioned_docs/version-0.70.6/reference/starlark-instructions.md b/docs/versioned_docs/version-0.70.6/reference/starlark-instructions.md new file mode 100644 index 0000000000..24b99d8a97 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/starlark-instructions.md @@ -0,0 +1,629 @@ +--- +title: Starlark Instructions +sidebar_label: Starlark Instructions +sidebar_position: 3 +--- + +This page lists out the Kurtosis instructions that are available in Starlark. + +**GENERAL NOTE:** In Python, it is very common to name function parameters that are optional. E.g.: + +```python +def do_something(required_arg, optional_arg="default_value") +``` + +In Kurtosis Starlark, all parameters can be referenced by name regardless of whether they are required or not. We do this to allow for ease-of-reading clarity. Mandatory and optional parameters will be indicated in the comment above the field. + +Similarly, all function arguments can be provided either positionally or by name. E.g. a function signature of: + +```python +def make_pizza(size, topping = "pepperoni") +``` + +Can be called in any of the following ways: + +```python +# 1. Only the required argument filled, positionally +make_pizza("16cm") + +# 2. Only the required argument filled, by name +make_pizza(size = "16cm") + +# 3. Both arguments filled, positionally +make_pizza("16cm", "mushroom") + +# 4. Both arguments filled, mixing position and name +make_pizza("16cm", topping = "mushroom") + +# 5. Both arguments filled, by name +make_pizza(size = "16cm", topping = "mushroom") +``` + +We recommend the last style (naming both positional and optional args), for reading clarity. + +### add_service + +The `add_service` instruction on the [`plan`][plan-reference] object adds a service to the Kurtosis enclave within which the script executes. + +```python +service = plan.add_service( + # The service name of the service being created. + # The service name is a reference to the service, which can be used in the future to refer to the service. + # Service names of active services are unique per enclave. + # MANDATORY + service_name = "example-datastore-server-1", + + # The configuration for this service. See the 'ServiceConfig' section of 'Starlark Types' from the sidebar for more information. + # MANDATORY + config = service_config, +) +``` + +For more info about the `config` argument, see [ServiceConfig][starlark-types-service-config] + +:::info +See [here][files-artifacts-reference] for more details on files artifacts. +::: + +The `add_service` function returns a `service` object that contains service information in the form of [future references][future-references-reference] that can be used later in the script. The `service` struct has: +- A `hostname` property representing [a future reference][future-references-reference] to the service's hostname. +- An `ip_address` property representing [a future reference][future-references-reference] to the service's IP address. +- A `ports` dictionary containing [future reference][future-references-reference] information about each port that the service is listening on. +- A `name` property representing the name of the service. + +The value of the `ports` dictionary is an object with three properties, `number`, `transport_protocol` and `application_protocol` (optional), which themselves are [future references][future-references-reference]. + +Example: +```python +dependency = plan.add_service( + service_name = "dependency", + config = ServiceConfig( + image = "dependency", + ports = { + "http": PortSpec(number = 80), + }, + ), +) + +dependency_http_port = dependency.ports["http"] + +plan.add_service( + service_name = "dependant", + config = ServiceConfig( + env_vars = { + "DEPENDENCY_URL": "http://{}:{}".format(dependency.ip_address, dependency_http_port.number), + }, + ), +) +``` + +### add_services + +The `add_services` instruction on the [`plan`][plan-reference] object adds multiple services all at once. + +The main advantage compared to calling [add_service][add-service] multiple times is that one call to `add_services` +will add multiple services at once. Currently, it can process up to 4 services concurrently, therefore reducing the +total time by a factor of nearly 4. + +Similar to `add_service`, it takes a map of service names to service configuration objects as input and returns a map +of service names to service objects. + +```python +all_services = plan.add_services( + # A map of service_name -> ServiceConfig for all services that needs to be added. + # See the 'ServiceConfig' section of 'Starlark Types' from the sidebar for more information on this type. + # MANDATORY + configs = { + "example-datastore-server-1": datastore_server_config_1, + "example-datastore-server-2": datastore_server_config_2, + }, +) +``` + +:::caution + +`add_services` will succeed if and only if all services are successfully added. If any one fails, the entire batch of +services will be rolled back and the instruction will return an execution error. + +::: + +The number of services being added concurrently is tunable by the `--parallelism` flag of the run command (see more on the [`run`](./cli/run-starlark.md) reference). + +### assert + +The `assert` on the [`plan`][plan-reference] object instruction fails the Starlark script or package with an execution error if the assertion defined fails. + +```python +plan.assert( + # The value currently being asserted. + # MANDATORY + value = "test1", + + # The assertion is the comparison operation between value and target_value. + # Valid values are "==", "!=", ">=", "<=", ">", "<" or "IN" and "NOT_IN" (if target_value is list). + # MANDATORY + assertion = "==", + + # The target value that value will be compared against. + # MANDATORY + target_value = "test2", +) # This fails in runtime given that "test1" == "test2" is false + +plan.assert( + # Value can also be a runtime value derived from a `get_value` call + value = response["body"], + assertion = "==", + target_value = 200, +) +``` + +:::caution + +Asserts are typed, so running + +```python +plan.assert( + value = "0", + assertion = "==", + target_value = 0, +) +``` + +Will fail. If needed, you can use the `extract` feature to parse the types of your outputs. +::: + +### exec + +The `exec` instruction on the [`plan`][plan-reference] object executes commands on a given service as if they were running in a shell on the container. + +```python +exec_recipe = ExecRecipe( + # The actual command to execute. + # Each item corresponds to one shell argument, so ["echo", "Hello world"] behaves as if you ran "echo" "Hello world" in the shell. + # MANDATORY + command = ["echo", "Hello, world"], +) + +result = plan.exec( + # The recipe that will determine the exec to be performed. + # Valid values are of the following types: (ExecRecipe) + # MANDATORY + recipe = exec_recipe, + + # If the recipe returns a code that does not belong on this list, this instruction will fail. + # OPTIONAL (Defaults to [0]) + acceptable_codes = [0, 0], # Here both 0 and 1 are valid codes that we want to accept and not fail the instruction + + # If False, instruction will never fail based on code (acceptable_codes will be ignored). + # You can chain this call with assert to check codes after request is done. + # OPTIONAL (Defaults to False) + skip_code_check = False, + + # A Service name designating a service that already exists inside the enclave + # If it does not, a validation error will be thrown + # MANDATORY + service_name = "my-service", +) + +plan.print(result["output"]) +plan.print(result["code"]) +``` + +The instruction returns a `dict` whose values are [future reference][future-references-reference] to the output and exit code of the command. `result["output"]` is a future reference to the output of the command, and `result["code"]` is a future reference to the exit code. + +They can be chained to [`assert`][assert] and [`wait`][wait]: + +```python +exec_recipe = ExecRecipe( + service_name = "my_service", + command = ["echo", "Hello, world"], +) + +result = plan.exec(exec_recipe) +plan.assert(result["code"], "==", 0) + +plan.wait(exec_recipe, "output", "!=", "Greetings, world") +``` + +### import_module + +The `import_module` function imports the symbols from a Starlark script specified by the given [locator][locators-reference], and requires that the calling Starlark script is part of a [package][packages-reference]. + +```python +# Import the code to namespaced object +lib = import_module("github.com/foo/bar/src/lib.star") + +# Use code from the imported module +lib.some_function() +lib.some_variable +``` + +NOTE: We chose not to use the normal Starlark `load` primitive due to its lack of namespacing. By default, the symbols imported by `load` are imported to the global namespace of the script that's importing them. We preferred module imports to be namespaced, in the same way that Python does by default with its `import` statement. + +### print + +`print` on the [`plan`][plan-reference] object will add an instruction to the plan to print the string. When the `print` instruction is executed during the [Execution Phase][multi-phase-runs-reference], [future references][future-references-reference] will be replaced with their execution-time values. + +``` +plan.print("Any string here") +``` + +### read_file + +The `read_file` function reads the contents of a file specified by the given [locator][locators-reference], and requires that the Starlark script is part of a [package][packages-reference]. `read_file` executes [at interpretation time][multi-phase-runs-reference] so the file contents won't be displayed in the preview. + + ```python +contents = read_file( + # The Kurtosis locator of the file to read. + # MANDATORY + src = "github.com/kurtosis-tech/datastore-army-package/README.md", +) + ``` + +### remove_connection + +As opposed to `set_connection`, `remove_connection` removes a connection override between two [subnetworks][subnetworks-reference]. The default connection cannot be removed; it can only be updated using [set_connection][set-connection]. + +```python +remove_connection( + # The subnetwork connection that will be removed + # If any of those two subnetworks does not currently have services, this instruction will not do anything. + # MANDATORY + subnetworks = ("subnetwork_1", "subnetwork_2"), + +) +``` + +### remove_service + +The `remove_service` instruction on the [`plan`][plan-reference] object removes a service from the enclave in which the instruction executes in. + +```python +plan.remove_service( + # The service name of the service to be removed. + # MANDATORY + service_name = "my_service", +) +``` + +### render_templates + +`render_templates` on the [`plan`][plan-reference] object combines a template and data to produce a [files artifact][files-artifacts-reference]. Files artifacts can be used with the `files` property in the service config of `add_service`, allowing for reuse of config files across services. + +```python +# Example data to slot into the template +template_data = { + "Name" : "Stranger", + "Answer": 6, + "Numbers": [1, 2, 3], + "UnixTimeStamp": 1257894000, + "LargeFloat": 1231231243.43, + "Alive": True, +} + +artifact_name = plan.render_templates( + # A dictionary where: + # - Each key is a filepath that will be produced inside the output files artifact + # - Each value is the template + data required to produce the filepath + # Multiple filepaths can be specified to produce a files artifact with multiple files inside. + # MANDATORY + config = { + "/foo/bar/output.txt": struct( + # The template to render, which should be formatted in Go template format: + # https://pkg.go.dev/text/template#pkg-overview + # MANDATORY + template="Hello {{.Name}}. The sum of {{.Numbers}} is {{.Answer}}. My favorite moment in history {{.UnixTimeStamp}}. My favorite number {{.LargeFloat}}. Am I Alive? {{.Alive}}", + + # The data to slot into the template, can be a struct or a dict + # The keys should exactly match the keys in the template. + # MANDATORY + data=template_data, + ), + }, + + # The name to give the files artifact that will be produced. + # If not specified, it will be auto-generated. + # OPTIONAL + name = "my-artifact", +) +``` + +The return value is a [future reference][future-references-reference] to the name of the [files artifact][files-artifacts-reference] that was generated, which can be used with the `files` property of the service config of the `add_service` command. + +### request + +The `request` instruction on the [`plan`][plan-reference] object executes either a POST or GET HTTP request, saving its result in a [future references][future-references-reference]. + +To make a GET or POST request, simply set the `recipe` field to use the specified [GetHttpRequestRecipe][starlark-types-get-http-recipe] or the [PostHttpRequestRecipe][starlark-types-post-http-recipe]. + +```python +http_response = plan.request( + # The recipe that will determine the request to be performed. + # Valid values are of the following types: (GetHttpRequestRecipe, PostHttpRequestRecipe) + # MANDATORY + recipe = request_recipe, + + # If the recipe returns a code that does not belong on this list, this instruction will fail. + # OPTIONAL (Defaults to [200, 201, ...]) + acceptable_codes = [200, 500], # Here both 200 and 500 are valid codes that we want to accept and not fail the instruction + + # If False, instruction will never fail based on code (acceptable_codes will be ignored). + # You can chain this call with assert to check codes after request is done. + # OPTIONAL (defaults to False) + skip_code_check = false, + + # A service name designating a service that already exists inside the enclave + # If it does not, a validation error will be thrown + # MANDATORY + service_name = "my_service", +) +plan.print(get_response["body"]) # Prints the body of the request +plan.print(get_response["code"]) # Prints the result code of the request (e.g. 200, 500) +plan.print(get_response["extract.extracted-field"]) # Prints the result of running ".name.id" query, that is saved with key "extracted-field" +``` + +The instruction returns a response, which is a `dict` with following key-value pair; the values are a [future reference][future-references-reference] +* `response["code"]` - returns the future reference to the `status code` of the response +* `response["body"]` - returns the future reference to the `body` of the the response +* `response["extract.some-custom-field"]` - it is an optional field and returns the future reference to the value extracted from `body`, which is explained below. + +#### extract + +`jq`'s [regular expressions](https://stedolan.github.io/jq/manual/) is used to extract the information from the response `body` and is assigned to a custom field. **The `response["body"]` must be a valid json object for manipulating data using `extractions`**. A valid `response["body"]` can be used for extractions. See below for an example of how this can be done for the [PostHttpRequestRecipe][starlark-types-post-http-recipe]: + + ```python + # Assuming response["body"] looks like {"result": {"foo": ["hello/world/welcome"]}} +post_request_recipe = PostHttpRequestRecipe( + ... + extract = { + "second-element-from-list-head": '.result.foo | .[0] | split ("/") | .[1]', + }, +) +post_response = plan.request( + recipe = post_request_recipe, +) +# response["extract.second-element-from-list-head"] is "world" +# response["body"] is {"result": {"foo": ["hello/world/welcome"]}} +# response["code"] is 200 +``` + +NOTE: In the above example, `response` also has a custom field `extract.second-element-from-list-head` and the value is `world` which is extracted from the `response[body]`. + +These fields can be used in conjunction with [`assert`][assert] and [`wait`][wait] instructions, like so: +```python +# Following the example above, response["extract.second-element-from-list-head"] is world +post_response = plan.request( + recipe = post_request_recipe, +) + +# Assert if the extracted field in the response is world +plan.assert(response["extract.second-element-from-list-head"], "==", "world") + +# Make a post request and check if the extracted field in the response is world +plan.wait(post_request_recipe, "extract.second-element-from-list-head", "==", "world") +``` + +NOTE: `jq` returns a typed output that translates into the correspondent Starlark type. You can cast it using `jq` to match +your desired output type: + +```python +# Assuming response["body"] looks like {"url": "posts/1"}} +post_request_recipe = PostHttpRequestRecipe( + ... + extract = { + "post-number": '.url | split ("/") | .[1]', + "post-number-as-int": '.url | split ("/") | .[1] | tonumber', + }, +) +response = plan.request( + recipe = post_request_recipe, +) +# response["extract.post-number"] is "1" (starlark.String) +# response["extract.post-number-as-int"] is 1 (starlark.Int) +``` + +For more details see [ `jq`'s builtin operators and functions](https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions) + +### set_connection + +Kurtosis uses a *default connection* to configure networking for any created subnetwork. +The `set_connection` can be used for two purposes: + +1. Used with the `subnetworks` argument, it will override the default connection between the two specified [subnetworks][subnetworks-reference]. +```python +set_connection( + # The subnetwork connection that will be be overridden + # OPTIONAL: See 2. below + subnetworks = ("subnetwork_1", "subnetwork_2"), + + # The configuration for this connection. See the 'ConnectionConfig' section of 'Starlark Types' from the sidecar for more information. + # MANDATORY + config = connection_config, +) +``` + +2. Used with only the `config` argument, it will update the *default connection*. + +:::caution + +Doing so will _immediately_ affect all subnetwork connections that were not previously overridden. + +::: + +```python +set_connection( + # The configuration for this connection. See the 'ConnectionConfig' section of 'Starlark Types' from the sidecar for more information. + # MANDATORY + config = connection_config, +) +``` + +See [ConnectionConfig][starlark-types-connection-config] for more information on the mandatory `config` argument. + +:::important + +Say we are overriding a connection between two subnetworks, as shown below: + +```python + +connection_config = ConnectionConfig( + packet_delay_distribution = UniformPacketDelayDistribution( + ms = 500, + ), +) + +set_connection( + subnetworks = ("subnetworkA", "subnetworkB"), + config = connection_config, +) + +``` +If serviceA is in subnetworkA and serviceB is in subnetworkB, the effective latency for a TCP request between serviceA and serviceB will be 1000ms = 500ms x 2. This is because the latency is applied to both the request (serviceA -> serviceB) and the response (serviceB -> serviceA) +::: + + +### store_service_files + +`store_service_files` on the [`plan`][plan-reference] object copies files or directories from an existing service in the enclave into a [files artifact][files-artifacts-reference]. This is useful when work produced on one container is needed elsewhere. + +```python +artifact_name = plan.store_service_files( + # The service name of a preexisting service from which the file will be copied. + # MANDATORY + service_name = "example-service-name", + + # The path on the service's container that will be copied into a files artifact. + # MANDATORY + src = "/tmp/foo", + + # The name to give the files artifact that will be produced. + # If not specified, it will be auto-generated. + # OPTIONAL + name = "my-favorite-artifact-name", +) +``` + +The return value is a [future reference][future-references-reference] to the name of the [files artifact][files-artifacts-reference] that was generated, which can be used with the `files` property of the service config of the `add_service` command. + +### update_service + +The `update_service` instruction updates an existing service without restarting it. For now, only the [service subnetwork][subnetworks-reference] can be updated live. In this case, the service will be moved to the corresponding subnetwork. + +```python +update_service( + # A Service name designating a service that already exists inside the enclave + # If it does not, a validation error will be thrown + # MANDATORY + service_name = "example-datastore-server-1", + + # The changes to apply to this service. See the 'UpdateServiceConfig' section of 'Starlark Types' from the sidecar for more information. + # MANDATORY + config = update_service_config, +) +``` + +See [UpdateServiceConfig][starlark-types-update-service-config] for more information on the mandatory `config` argument. + +### upload_files + +`upload_files` on the [`plan`][plan-reference] object packages the files specified by the [locator][locators-reference] into a [files artifact][files-artifacts-reference] that gets stored inside the enclave. This is particularly useful when a static file needs to be loaded to a service container. + +```python +artifact_name = plan.upload_files( + # The file to upload into a files a files artifact + # Must be a Kurtosis locator. + # MANDATORY + src = "github.com/foo/bar/static/example.txt", + + # The name to give the files artifact that will be produced. + # If not specified, it will be auto-generated. + # OPTIONAL + name = "my-artifact", +) +``` + +The return value is a [future reference][future-references-reference] to the name of the [files artifact][files-artifacts-reference] that was generated, which can be used with the `files` property of the service config of the `add_service` command. + +### wait + +The `wait` instruction on the [`plan`][plan-reference] object fails the Starlark script or package with an execution error if the [assertion][assert] does not succeed in a given period of time. + +To learn more about the accepted recipe types, please checkout [ExecRecipe][starlark-types-exec-recipe], [GetHttpRequestRecipe][starlark-types-get-http-recipe] or [PostHttpRequestRecipe][starlark-types-post-http-recipe]. + +If it succeeds, it returns a [future references][future-references-reference] with the last recipe run. + + +```python +# This fails in runtime if response["code"] != 200 for each request in a 5 minute time span +response = plan.wait( + # The recipe that will be run until assert passes. + # Valid values are of the following types: (ExecRecipe, GetHttpRequestRecipe, PostHttpRequestRecipe) + # MANDATORY + recipe = recipe, + + # Wait will use the response's field to do the asssertions. To learn more about available fields, + # that can be used for assertions, please refer to exec and request instructions. + # MANDATORY + field = "code", + + # The assertion is the comparison operation between value and target_value. + # Valid values are "==", "!=", ">=", "<=", ">", "<" or "IN" and "NOT_IN" (if target_value is list). + # MANDATORY + assertion = "==", + + # The target value that value will be compared against. + # MANDATORY + target_value = 200, + + # The interval value is the initial interval suggestion for the command to wait between calls + # It follows a exponential backoff process, where the i-th backoff interval is rand(0.5, 1.5)*interval*2^i + # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration + # OPTIONAL (Default: "1s") + interval = "1s", + + # The timeout value is the maximum time that the command waits for the assertion to be true + # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration + # OPTIONAL (Default: "10s") + timeout = "5m", + + # A Service name designating a service that already exists inside the enclave + # If it does not, a validation error will be thrown + # MANDATORY + service_name = "example-datastore-server-1", +) +# If this point of the code is reached, the assertion has passed therefore the print statement will print "200" +plan.print(response["code"]) +``` + +Starlark Standard Libraries +--------------------------- + +The following Starlark libraries that ship with the `starlark-go` are included +in Kurtosis Starlark by default + +1. The Starlark [time](https://github.com/google/starlark-go/blob/master/lib/time/time.go#L18-L52) is a collection of time-related functions +2. The Starlark [json](https://github.com/google/starlark-go/blob/master/lib/json/json.go#L28-L74) module allows you `encode`, `decode` and `indent` JSON +4. The Starlark [struct](https://github.com/google/starlark-go/blob/master/starlarkstruct/struct.go) builtin allows you to create `structs` like the one used in [`add_service`](#add_service) + + + +[set-connection]: #set_connection +[add-service]: #add_service +[wait]: #wait +[assert]: #assert +[extract]: #extract + +[files-artifacts-reference]: ./files-artifacts.md +[future-references-reference]: ./future-references.md +[packages-reference]: ./packages.md +[locators-reference]: ./locators.md +[multi-phase-runs-reference]: ./multi-phase-runs.md +[plan-reference]: ./plan.md +[subnetworks-reference]: ./subnetworks.md + +[starlark-types-connection-config]: ./starlark-types.md#connectionconfig +[starlark-types-service-config]: ./starlark-types.md#serviceconfig +[starlark-types-update-service-config]: ./starlark-types.md#updateserviceconfig +[starlark-types-exec-recipe]: ./starlark-types.md#execrecipe +[starlark-types-post-http-recipe]: ./starlark-types.md#posthttprequestrecipe +[starlark-types-get-http-recipe]: ./starlark-types.md#gethttprequestrecipe diff --git a/docs/versioned_docs/version-0.70.6/reference/starlark-types.md b/docs/versioned_docs/version-0.70.6/reference/starlark-types.md new file mode 100644 index 0000000000..1bd0086f17 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/starlark-types.md @@ -0,0 +1,392 @@ +--- +title: Starlark Types +sidebar_label: Starlark Types +sidebar_position: 4 +--- + +This page lists out the Kurtosis types that are available in Starlark. + +## Type definitions + +### ConnectionConfig + +The `ConnectionConfig` is used to configure a connection between two [subnetworks][subnetworks-reference] (see [set_connection][starlark-instructions-set-connection]). + +```python +connection_config = ConnectionConfig( + # Percentage of packet lost each way between subnetworks + # OPTIONAL + # DEFAULT: 0.0 + packet_loss_percentage = 50.0, + + # Amount of delay added to packets each way between subnetworks + # OPTIONAL: Valid value are UniformPacketDelayDistribution or NormalPacketDelayDistribution + packet_delay_distribution = UniformPacketDelayDistribution( + # Delay in ms + ms = 500, + ), +) +``` + +:::tip +See [kurtosis.connection][connection-config-prebuilt] for pre-built [ConnectionConfig][connection-config] objects +::: + +### ExecRecipe + +The ExecRecipe can be used to run the `command` on the service (see [exec][starlark-instructions-exec] +or [wait][starlark-instructions-wait]) + +```python +exec_recipe = ExecRecipe( + # The actual command to execute. + # Each item corresponds to one shell argument, so ["echo", "Hello world"] behaves as if you ran "echo 'Hello World'" in the shell. + # MANDATORY + command = ["echo", "Hello, World"], +) +``` + +### GetHttpRequestRecipe + +The `GetHttpRequestRecipe` can be used to make `GET` requests to an endpoint, filter for the specific part of the response you care about, and assign that specific output to a key for later use. This can be useful for writing assertions, for example (i.e. validating the response you end up receiving looks the way you expect/intended). + +```python +get_request_recipe = GetHttpRequestRecipe( + # The port ID that is the server port for the request + # MANDATORY + port_id = "my_port", + + # The endpoint for the request + # MANDATORY + endpoint = "/endpoint?input=data", + + # The extract dictionary can be used for filtering specific parts of a HTTP GET + # request and assigning that output to a key-value pair, where the key is the + # reference variable and the value is the specific output. + # + # Specifcally: the key is the way you refer to the extraction later on and + # the value is a 'jq' string that contains logic to extract parts from response + # body that you get from the HTTP GET request. + # + # To lean more about jq, please visit https://devdocs.io/jq/ + # OPTIONAL + extract = { + "extractfield" : ".name.id", + }, +) +``` + +:::info +Important - the `port_id` field accepts user-defined port IDs that are assigned to a port in a service's port map, using `ServiceConfig`. For example, if our service's `ServiceConfig` has the following port mappings: + +``` + test-service-config = ServiceConfig( + ports = { + // "port_id": port_number + "http": 5000, + "grpc": 3000, + ... + }, + ... + ) +``` + +The user-defined port IDs in the above `ServiceConfig` are: `http` and `grpc`. Both of these user-defined port IDs can therefore be used to create http request recipes (`GET` OR `POST`), such as: + +``` + recipe = GetHttpRequestRecipe( + port_id = "http", + service_name = "service-using-test-service-config", + endpoint = "/ping", + ... + ) +``` + +The above recipe, when used with `request` or `wait` instruction, will make a `GET` request to a service (the `service_name` field must be passed as an instruction's argument) on port `5000` with the path `/ping`. +::: + +### PostHttpRequestRecipe + +The `PostHttpRequestRecipe` can be used to make `POST` requests to an endpoint. + +```python +post_request_recipe = PostHttpRequestRecipe( + # The port ID that is the server port for the request + # MANDATORY + port_id = "my_port", + + # The endpoint for the request + # MANDATORY + endpoint = "/endpoint", + + # The content type header of the request (e.g. application/json, text/plain, etc) + # MANDATORY + content_type = "application/json", + + # The body of the request + # MANDATORY + body = "{\"data\": \"this is sample body for POST\"}", + + # The extract dictionary takes in key-value pairs where: + # Key is a way you refer to the extraction later on + # Value is a 'jq' string that contains logic to extract from response body + # # To lean more about jq, please visit https://devdocs.io/jq/ + # OPTIONAL + extract = { + "extractfield" : ".name.id", + }, +) +``` + +:::caution + +Make sure that the endpoint returns valid JSON response for both POST and GET requests. + +::: + +### UniformPacketDelayDistribution + +The `UniformPacketDelayDistribution` creates a packet delay distribution with constant delay in `ms`. This can be used in conjuction with [`ConnectionConfig`][connection-config] to introduce latency between two [`subnetworks`][subnetworks-reference]. See [`set_connection`][starlark-instructions-set-connection] instruction to learn more about its usage. + +```python + +delay = UniformPacketDelayDistribution( + # Non-Negative Integer + # Amount of constant delay added to outgoing packets from the subnetwork + # MANDATORY + ms = 1000, +) +``` + +### NormalPacketDelayDistribution + +The `NormalPacketDelayDistribution` creates a packet delay distirbution that follows a normal distribution. This can be used in conjuction with [`ConnectionConfig`][connection-config] to introduce latency between two [`subnetworks`][subnetworks-reference]. See [`set_connection`][starlark-instructions-set-connection] instruction to learn more about its usage. + +```python + +delay = NormalPacketDelayDistribution( + # Non-Negative Integer + # Amount of mean delay added to outgoing packets from the subnetwork + # MANDATORY + mean_ms = 1000, + + # Non-Negative Integer + # Amount of variance (jitter) added to outgoing packets from the subnetwork + # MANDATORY + std_dev_ms = 10, + + # Non-Negative Float + # Percentage of correlation observed among packets. It means that the delay observed in next packet + # will exhibit a corrlation factor of 10.0% with the previous packet. + # OPTIONAL + # DEFAULT = 0.0 + correlation = 10.0, +) +``` + +### PortSpec + +This `PortSpec` constructor creates a PortSpec object that encapsulates information pertaining to a port. + +```python +port_spec = PortSpec( + # The port number which we want to expose + # MANDATORY + number = 3000, + + # Transport protocol for the port (can be either "TCP" or "UDP") + # OPTIONAL (DEFAULT:"TCP") + transport_protocol = "TCP", + + # Application protocol for the port that will be displayed in front of URLs containing the port + # For example: + # "http" to get a URL of "http://..." + # "postgresql" to get a URL of "postgresql://..." + # OPTIONAL + application_protocol = "http", +) +``` +The above constructor returns a `PortSpec` object that contains port information in the form of a [future reference][future-references-reference] and can be used with +[add_service][starlark-instructions-add-service] to create services. + +### ReadyConditions + +The `ReadyConditions` can be used to execute a readiness check after a service is started to confirm that it is ready to receive connections and traffic + +```python +ready_conditions = ReadyConditions( + + # The recipe that will be used to check service's readiness. + # Valid values are of the following types: (ExecRecipe, GetHttpRequestRecipe or PostHttpRequestRecipe) + # MANDATORY + recipe = GetHttpRequestRecipe( + port_id = "http", + endpoint = "/ping", + ), + + # The `field's value` will be used to do the asssertions. To learn more about available fields, + # that can be used for assertions, please refer to exec and request instructions. + # MANDATORY + field = "code", + + # The assertion is the comparison operation between value and target_value. + # Valid values are "==", "!=", ">=", "<=", ">", "<" or "IN" and "NOT_IN" (if target_value is list). + # MANDATORY + assertion = "==", + + # The target value that value will be compared against. + # MANDATORY + target_value = 200, + + # The interval value is the initial interval suggestion for the command to wait between calls + # It follows a exponential backoff process, where the i-th backoff interval is rand(0.5, 1.5)*interval*2^i + # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration + # OPTIONAL (Default: "1s") + interval = "1s", + + # The timeout value is the maximum time that the readiness check waits for the assertion to be true + # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration + # OPTIONAL (Default: "15m") + timeout = "5m", +) +``` + +### ServiceConfig + +The `ServiceConfig` is used to configure a service when it is added to an enclave (see [add_service][starlark-instructions-add-service]). + +```python +config = ServiceConfig( + # The name of the container image that Kurtosis should use when creating the service’s container. + # MANDATORY + image = "kurtosistech/example-datastore-server", + + # The ports that the container should listen on, identified by a user-friendly ID that can be used to select the port again in the future. + # If no ports are provided, no ports will be exposed on the host machine, unless there is an EXPOSE in the Dockerfile + # OPTIONAL (Default: {}) + ports = { + "grpc": PortSpec( + # The port number which we want to expose + # MANDATORY + number = 3000, + + # Transport protocol for the port (can be either "TCP" or "UDP") + # Optional (DEFAULT:"TCP") + transport_protocol = "TCP", + + # Application protocol for the port + # Optional + application_protocol = "http", + ), + }, + + # A mapping of path_on_container_where_contents_will_be_mounted -> files_artifact_id_to_mount + # For more info on what a files artifact is, see below + # OPTIONAL (Default: {}) + files = { + "path/to/file/1": files_artifact_1, + "path/to/file/2": files_artifact_2, + }, + + # The ENTRYPOINT statement hardcoded in a container image's Dockerfile might not be suitable for your needs. + # This field allows you to override the ENTRYPOINT when the container starts. + # OPTIONAL (Default: []) + entrypoint = [ + "bash", + ], + + # The CMD statement hardcoded in a container image's Dockerfile might not be suitable for your needs. + # This field allows you to override the CMD when the container starts. + # OPTIONAL (Default: []) + cmd = [ + "-c", + "sleep 99", + ], + + # Defines environment variables that should be set inside the Docker container running the service. + # This can be necessary for starting containers from Docker images you don’t control, as they’ll often be parameterized with environment variables. + # OPTIONAL (Default: {}) + env_vars = { + "VAR_1": "VALUE_1", + "VAR_2": "VALUE_2", + }, + + # ENTRYPOINT, CMD, and ENV variables sometimes need to refer to the container's own IP address. + # If this placeholder string is referenced inside the 'entrypoint', 'cmd', or 'env_vars' properties, the Kurtosis engine will replace it at launch time + # with the container's actual IP address. + # OPTIONAL (Default: "KURTOSIS_IP_ADDR_PLACEHOLDER") + private_ip_address_placeholder = "KURTOSIS_IP_ADDRESS_PLACEHOLDER", + + # The maximum amount of CPUs the service can use, in millicpu/millicore. + # OPTIONAL (Default: no limit) + cpu_allocation = 1000, + + # The maximum amount of memory, in megabytes, the service can use. + # OPTIONAL (Default: no limit) + memory_allocation = 1024, + + # Defines the subnetwork in which the service will be started. + # OPTIONAL (Default: "default") + subnetwork = "service_subnetwork", + + # This field can be used to check the service's readiness after this is started + # to confirm that it is ready to receive connections and traffic + # OPTIONAL (Default: no ready conditions) + ready_conditions = ReadyConditions(...) +) +``` +The `ports` dictionary argument accepts a key value pair, where `key` is a user defined unique port identifier and `value` is a [PortSpec][port-spec] object. + +The `files` dictionary argument accepts a key value pair, where `key` is the path where the contents of the artifact will be mounted to and `value` is a file artifact name. (see [upload_files][starlark-instructions-upload-files], [render_templates][starlark-instructions-render-templates] and [store_service_files][starlark-instructions-store-service-files] to learn more about on how to create file artifacts) + +For more info about the `subnetwork` argument, see [Kurtosis subnetworks][subnetworks-reference]. + +You can see how to configure the [`ReadyConditions` type here][ready-conditions]. + +### UpdateServiceConfig + +The `UpdateServiceConfig` contains the attributes of [ServiceConfig][service-config] that are live-updatable. For now, only the `subnetwork`[subnetworks-reference] attribute of a service can be updated once the service is started. + +```python +update_service_config = UpdateServiceConfig( + # The subnetwork to which the service will be moved. + # "default" can be used to move the service to the default subnetwork + # MANDATORY + subnetwork = "subnetwork_1", +) +``` + +## The global `kurtosis` object + +Kurtosis provides "pre-built" values for types that will be broadly used. Those values are provided through the `kurtosis` object. It is available globally and doesn't need to be imported. + +### `connection` + +#### `ALLOWED` + +`kurtosis.connection.ALLOWED` is equivalent to [ConnectionConfig][connection-config] with `packet_loss_percentage` set to `0` and `packet_delay` set to `PacketDelay(delay_ms=0)`. It represents a [ConnectionConfig][connection-config] that _allows_ all connection between two subnetworks with no delay and packet loss. + +#### `BLOCKED` + +`kurtosis.connection.BLOCKED` is equivalent to [ConnectionConfig][connection-config] with `packet_loss_percentage` set to `100` and `packet_delay` set to `PacketDelay(delay_ms=0)`. It represents a [ConnectionConfig][connection-config] that _blocks_ all connection between two subnetworks. + + +[connection-config]: #connectionconfig +[service-config]: #serviceconfig +[port-spec]: #portspec +[ready-conditions]: #readyconditions + +[connection-config-prebuilt]: #connection + +[future-references-reference]: ./future-references.md +[subnetworks-reference]: ./subnetworks.md + +[starlark-instructions-add-service]: ./starlark-instructions.md#add_service +[starlark-instructions-set-connection]: ./starlark-instructions.md#set_connection +[starlark-instructions-request]: ./starlark-instructions.md#request +[starlark-instructions-wait]: ./starlark-instructions.md#wait +[starlark-instructions-exec]: ./starlark-instructions.md#exec +[starlark-instructions-upload-files]: ./starlark-instructions.md#upload_files +[starlark-instructions-store-service-files]: ./starlark-instructions.md#store_service_files +[starlark-instructions-render-templates]: ./starlark-instructions.md#render_templates + diff --git a/docs/versioned_docs/version-0.70.6/reference/subnetworks.md b/docs/versioned_docs/version-0.70.6/reference/subnetworks.md new file mode 100644 index 0000000000..c7cde86156 --- /dev/null +++ b/docs/versioned_docs/version-0.70.6/reference/subnetworks.md @@ -0,0 +1,41 @@ +--- +title: Subnetworks +sidebar_label: Subnetworks +--- + +:::tip + +Want to get started with subnetworks? See how to easily simulate a networking failure [here][networking-failure-guide] + +::: + +A service started inside a Kurtosis enclave will by default be able to communicate with all other services inside the same enclave. To change that behavior, Kurtosis exposes the concept of *subnetworks*. + +A subnetwork is a way to group together an arbitrary number of services from the same enclave. It is very lightweight and it can be instantiated by "tagging" each service with a subnetwork name (see [add_service][add-service] and [update_service][update-service]). A service added to an enclave without a subnetwork specified is added to the default subnetwork (called `default`). + +All services with the same "subnetwork tag" will belong to the same subnetwork, and networking can then be configured _accross subnetworks_. All services in the same subnetwork (including the `default` one) will always be able to communicate. + +The connection configuration between two subnetworks inherits a *default connection* defined in Kurtosis. It is set to allow all communications when the enclave starts but it can be changed using [set_connection][set-connection]. + +To have fine grained control, the connection between two specific subnetworks can be overridden also using the same [set_connection][set-connection]. The override can be removed using [remove_connection][remove-connection]. + +:::caution + +This functionaility is only available for Kurtosis running on Docker. Kurtosis running on Kubernetes cannot use subnetworks yet, and instructions requiring it will throw an error. + +::: + +:::caution + +This functionality must be enabled manually per enclave using the CLI. When running Starlark scripts or packages using this feature, add the `--with-subnetworks` optional flag. + +::: + + + + +[add-service]: ./starlark-instructions.md#add_service +[update-service]: ./starlark-instructions.md#update_service +[set-connection]: ./starlark-instructions.md#set_connection +[remove-connection]: ./starlark-instructions.md#remove_connection +[networking-failure-guide]: ../guides/simulating-networking-failure.md diff --git a/docs/versioned_sidebars/version-0.70.6-sidebars.json b/docs/versioned_sidebars/version-0.70.6-sidebars.json new file mode 100644 index 0000000000..80cb195b00 --- /dev/null +++ b/docs/versioned_sidebars/version-0.70.6-sidebars.json @@ -0,0 +1,50 @@ +{ + "main": [ + "home", + "quickstart", + { + "type": "category", + "label": "Guides", + "collapsed": true, + "items": [ + { + "type": "autogenerated", + "dirName": "guides" + } + ] + }, + { + "type": "category", + "label": "Explanations", + "collapsed": true, + "items": [ + { + "type": "autogenerated", + "dirName": "explanations" + } + ] + }, + { + "type": "category", + "label": "Reference", + "collapsed": true, + "items": [ + { + "type": "autogenerated", + "dirName": "reference" + } + ] + }, + { + "type": "link", + "label": "Examples", + "href": "https://github.com/kurtosis-tech/examples" + }, + { + "type": "link", + "label": "Kurtosis-Managed Packages", + "href": "https://github.com/kurtosis-tech?q=package+in%3Aname&type=all&language=&sort=" + }, + "changelog" + ] +} diff --git a/docs/versions.json b/docs/versions.json index 6dfa5a4d4b..863bd39198 100644 --- a/docs/versions.json +++ b/docs/versions.json @@ -1,4 +1,5 @@ [ + "0.70.6", "0.70.5", "0.70.4", "0.70.3", diff --git a/version.txt b/version.txt index 3a62b9525f..1c25880c4a 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.70.5 +0.70.6